1 / 1 / 0
Регистрация: 11.10.2020
Сообщений: 58
1

Ошибка деструктора класса при работе с бинарным файлом

05.11.2020, 07:15. Показов 1028. Ответов 16
Метки нет (Все метки)

Догадываюсь, что ошибка в неправильном взаимодействии с моей строкой, но не могу найти причину.

class
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
 
class stroka {
    char* marka;        // Указатель на массив char
    int max_size;       // Максимальный размер массива
    int size;           // Текущий размер массива
    static int count;   // Количество экземпляров класса
public:
 
stroka::stroka() {      // Конструктор по умолчанию
    this->marka = nullptr;
    this->max_size = 0;
    this->size = 0;
    this->count++;
}
 
stroka::stroka(const char* marka, int max_size) {       // Конструктор с параметрами
    this->marka = strdup(marka);
    this->max_size = max_size;
    this->size = strlen(marka) + 1;
    this->count++;
}
 
stroka::~stroka() {     // Деструктор
    delete[] marka;
}
 
ostream& operator<<(ostream& os, const stroka& p) {     // Вывод объекта в консоль
    os << "string: " << p.marka << " size: " << p.size << " max size: " << p.max_size << endl;
    return os;
}
 
ostream& stroka::writeToBin(ostream& stream) {
    stream.write((char*)&marka, sizeof(marka));
    stream.write((char*)&size, sizeof(size));
    stream.write((char*)&max_size, sizeof(max_size));
    return stream;
}
 
istream& stroka::readFromBin(istream& stream) {
    stream.read((char*)&marka, sizeof(marka));
    stream.read((char*)&size, sizeof(size));
    stream.read((char*)&max_size, sizeof(max_size));
    return stream;
 
}
main
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main() {
    setlocale(LC_ALL, "Rus");
    
    stroka a1("Hello World!",14);
    stroka a2("qwerty", 8);
    stroka a3("Some text", 11);
    stroka b1,b2,b3;
 
    ofstream bfile1("bFile.bin", ios::binary);
    a1.writeToBin(bfile1);
    a2.writeToBin(bfile1);
    a3.writeToBin(bfile1);
    bfile1.close();
 
    ifstream bfile2("bFile.bin", ios::binary);
    b1.readFromBin(bfile2);
    b2.readFromBin(bfile2);
    b3.readFromBin(bfile2);
    cout << b1 << b2 << b3;
    bfile2.close();
 
    return 0;
}
Миниатюры
Ошибка деструктора класса при работе с бинарным файлом  
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.11.2020, 07:15
Ответы с готовыми решениями:

Проблемка при работе с бинарным файлом
Q живым.Есть проблема при работе с бинарным файлом.В файле 1.dat пытался разместить 10 чисел,но...

Переезд проекта из delphi7 в xe5 / ошибка при работе с бинарным файлом
Доброго времени суток. Недавно переехал с семёрки на xe5, перенёс проект и... он вешается....

Ошибка при работе деструктора
#include&lt;iostream&gt; #include&lt;time.h&gt; #include&lt;Windows.h&gt; #include &lt;stdio.h&gt; #include &lt;conio.h&gt;...

Ошибка при работе деструктора объекта p1
тут простой класс очереди с конструктором копирования,деструктором,и функцией print,которая выводит...

16
Любитель чаепитий
3627 / 1714 / 532
Регистрация: 24.08.2014
Сообщений: 5,795
Записей в блоге: 1
05.11.2020, 07:23 2
Цитата Сообщение от NkL Посмотреть сообщение
this->marka = strdup(marka);
функция strdup использует malloc для выделения памяти. поэтому применять к ней operator delete[] некорректно.
используйте ::free(marka);.
0
1 / 1 / 0
Регистрация: 11.10.2020
Сообщений: 58
05.11.2020, 09:50  [ТС] 3
Цитата Сообщение от GbaLog- Посмотреть сообщение
функция strdup использует malloc для выделения памяти. поэтому применять к ней operator delete[] некорректно.
используйте ::free(marka);.
Поменял delete[] marka на free(marka). Та же самая ошибка вылетает при работе деструкторов.
0
7 / 3 / 4
Регистрация: 24.01.2017
Сообщений: 124
05.11.2020, 10:52 4
А какой именно ассерт не срабатывает? Посмотрите.
0
Любитель чаепитий
3627 / 1714 / 532
Регистрация: 24.08.2014
Сообщений: 5,795
Записей в блоге: 1
05.11.2020, 11:20 5
Цитата Сообщение от NkL Посмотреть сообщение
C++
1
stream.read((char*)&marka, sizeof(marka));
ошибка в этой строке.
взглянем на вызывающий код:
Цитата Сообщение от NkL Посмотреть сообщение
C++
1
2
3
stroka b1,b2,b3;
//...
b1.readFromBin(bfile2);
между этими строками вы ничего с переменной b1 не делаете. в результате чего marka там nullptr, а size и max_size равны 0.
в строке stream.read() вы должны передать char * и std::streamsize. вы же берёте адрес у члена вашего класса marka и получаете char ** и кастите его к char *, а кол-во данных для чтения у вас sizeof(marka), то есть размер указателя.
таким образом, вы читаете sizeof(char *) в переменную char **, который указывает на ваш указатель marka, то есть внутри функции ваш указатель попросту перезаписывается на какой-то мусор(на самом деле на байты, которые вы записали в файл ранее).
то есть по выходу из функции marka уже указывает не на nullptr, а на какой-то мусор.
в итоге при уничтожении строки вызывается free для какого-то мусора и на это ругается дебаггер.

вообще, нормальный путь реализации предполагает то, что вы записываете сначала размер, а потом саму строку, чтобы при чтении прочитать размер, выделить нужное кол-во памяти и потом уже в эту выделенную память прочитать саму строку. у вас всё наоборот и так работать не будет.
1
1 / 1 / 0
Регистрация: 11.10.2020
Сообщений: 58
05.11.2020, 11:20  [ТС] 6
Я понял, что происходит не так. У меня создаются объекты a, их поля записываются в бинарный файл. Потом создаются пустые объекты b, поля из бинарного файла записываются в эти объекты. Только вот адрес динамического массива символов не меняется, из-за чего у меня 2 раза освобождается память. Как нужно использовать функцию read, чтобы у массивов были разные адреса?
0
Любитель чаепитий
3627 / 1714 / 532
Регистрация: 24.08.2014
Сообщений: 5,795
Записей в блоге: 1
05.11.2020, 11:28 7
Цитата Сообщение от NkL Посмотреть сообщение
C++
1
2
3
stream.write((char*)&marka, sizeof(marka));
stream.write((char*)&size, sizeof(size));
stream.write((char*)&max_size, sizeof(max_size));
запись у вас, кстати, тоже неправильная. если вы заглянете в файл, то вряд ли увидите там строки, которые вы туда записываете.
почитайте про то, как функции read/write у std::i/ostream работают и какие аргументы она принимают.
и да, ещё раз, sizeof(marka) не даёт размер строки, он даёт размер указателя.
1
1 / 1 / 0
Регистрация: 11.10.2020
Сообщений: 58
05.11.2020, 12:20  [ТС] 8
Цитата Сообщение от GbaLog- Посмотреть сообщение
запись у вас, кстати, тоже неправильная. если вы заглянете в файл, то вряд ли увидите там строки, которые вы туда записываете.
почитайте про то, как функции read/write у std::i/ostream работают и какие аргументы она принимают.
и да, ещё раз, sizeof(marka) не даёт размер строки, он даёт размер указателя.
Я сейчас переписал на это. Но вылетает ошибка при чтении с файла поля marka. Вроде и передаю в аргументы размер строки, умноженный на размер символа, и указатель на мой массив.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
ostream& stroka::writeToBin(ostream& stream) {
    stream.write((char*)&size, sizeof(size));
    stream.write((char*)&max_size, sizeof(max_size));
    stream.write(marka, this->size * sizeof(char));
    return stream;
}
 
istream& stroka::readFromBin(istream& stream) {
    stream.read((char*)&size, sizeof(size));
    stream.read((char*)&max_size, sizeof(max_size));
    stream.read(marka, this->size * sizeof(char));
    return stream;
}
0
Любитель чаепитий
3627 / 1714 / 532
Регистрация: 24.08.2014
Сообщений: 5,795
Записей в блоге: 1
05.11.2020, 12:40 9
Лучший ответ Сообщение было отмечено NkL как решение

Решение

Цитата Сообщение от NkL Посмотреть сообщение
Вроде и передаю в аргументы размер строки, умноженный на размер символа, и указатель на мой массив.
вам нужно выделить память для marka перед чтением.
marka = malloc(this->size * sizeof(char));
1
1 / 1 / 0
Регистрация: 11.10.2020
Сообщений: 58
05.11.2020, 12:58  [ТС] 10
Цитата Сообщение от GbaLog- Посмотреть сообщение
вам нужно выделить память для marka перед чтением.
marka = malloc(this->size * sizeof(char));
malloc же возвращает значение void*, а у меня marka char*
0
Любитель чаепитий
3627 / 1714 / 532
Регистрация: 24.08.2014
Сообщений: 5,795
Записей в блоге: 1
05.11.2020, 13:00 11
Цитата Сообщение от NkL Посмотреть сообщение
malloc же возвращает значение void*, а у меня marka char*
ну приведите результат malloc к char *.
я бы предложил вам вообще везде использовать operator new и operator delete, т.к. это всё-таки с++, но аналога strdup для с++ нет, поэтому придётся копировать строку в два действия: выделение памяти, затем копирование.
1
1 / 1 / 0
Регистрация: 11.10.2020
Сообщений: 58
05.11.2020, 14:57  [ТС] 12
Цитата Сообщение от GbaLog- Посмотреть сообщение
ну приведите результат malloc к char *.
я бы предложил вам вообще везде использовать operator new и operator delete, т.к. это всё-таки с++, но аналога strdup для с++ нет, поэтому придётся копировать строку в два действия: выделение памяти, затем копирование.
Теперь на этом операторе при выводе p.size ошибка... А вот marka вывелась на экран
ostream& operator<<(ostream& os, stroka& p) { // Вывод объекта в консоль
os << "string: " << p.marka << " size: " << p.size << " max size: " << p.max_size << endl;
return os;
}
Ошибка деструктора класса при работе с бинарным файлом
0
Любитель чаепитий
3627 / 1714 / 532
Регистрация: 24.08.2014
Сообщений: 5,795
Записей в блоге: 1
05.11.2020, 15:51 13
Цитата Сообщение от NkL Посмотреть сообщение
Теперь на этом операторе при выводе p.size ошибка... А вот marka вывелась на экран
покажите код.
0
1 / 1 / 0
Регистрация: 11.10.2020
Сообщений: 58
05.11.2020, 16:14  [ТС] 14
Цитата Сообщение от GbaLog- Посмотреть сообщение
покажите код.
Может я набедокурил
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ostream& stroka::writeToBin(ostream& stream) {
    stream.write((char*)&size, sizeof(size));
    stream.write((char*)&max_size, sizeof(max_size));
    stream.write(marka, this->size * sizeof(char));
    return stream;
}
 
istream& stroka::readFromBin(istream& stream) {
    marka = (char*)(malloc(this->size * sizeof(char)));
    stream.read((char*)&size, sizeof(size));
    stream.read((char*)&max_size, sizeof(max_size));
    stream.read(marka, this->size * sizeof(char));
    return stream;
}
0
Любитель чаепитий
3627 / 1714 / 532
Регистрация: 24.08.2014
Сообщений: 5,795
Записей в блоге: 1
05.11.2020, 16:46 15
Цитата Сообщение от NkL Посмотреть сообщение
C++
1
marka = (char*)(malloc(this->size * sizeof(char)));
у вас на этом месте size == 0. вам нужно сначала прочитать размер в size, а потом уже выделять память.
1
1 / 1 / 0
Регистрация: 11.10.2020
Сообщений: 58
05.11.2020, 16:59  [ТС] 16
Цитата Сообщение от GbaLog- Посмотреть сообщение
у вас на этом месте size == 0. вам нужно сначала прочитать размер в size, а потом уже выделять память.
Благодарю, помогло Так должен выглядеть текст в бинарном файле?
Ошибка деструктора класса при работе с бинарным файлом
0
Любитель чаепитий
3627 / 1714 / 532
Регистрация: 24.08.2014
Сообщений: 5,795
Записей в блоге: 1
05.11.2020, 17:07 17
Цитата Сообщение от NkL Посмотреть сообщение
Так должен выглядеть текст в бинарном файле?
ну, вам лучше знать, ваша же программа. )
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.11.2020, 17:07

Ошибка при работе с файлом
Собственно при обработке процедуры, появляется ошибка: I/O error 103 Отладчик выделяет шестую...

Ошибка при работе с файлом
Пытался разобраться с записью и чтением из файла, посмотрел с десяток тем здесь, но столкнулся со...

Ошибка при работе с файлом
Суть задачи в том что надо надо с файла(пользователь сам вводит путь к файлу) Надо что бы в файле...

Ошибка при работе с .ini файлом
Прочитал, что хоть использование .ini файлов и устарело, но всё же кое-где практичнее системного...

Ошибка при работе с файлом в gedit
Не знаю, в чем проблема, но как только я хочу работать с файлом gedit, сразу же выдает ошибку....

Ошибка при работе с текстовым файлом
Пытаюсь написать простую программу для поиска всех возможных слов из букв, введённых пользователем....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.