освобождаемый указатель не был выделен (создание динамической копии класса)

#c #xcode7

#c #xcode7

Вопрос:

Мне нужно написать программу, в которой я должен создать класс с элементами, где память выделяется динамически. Когда я динамически создаю два экземпляра своего класса (m1 и m2) и создаю копию m1 (код: m1 = m2), компилятор сообщает следующее:

 C  (11253,0x100084000) malloc: *** error for object 0x1002000b0:
pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Program ended with exit code: 9
  

Вот мой класс:

 class CharArray {
private:
    char *array;
public:
//Конструкторы
CharArray() {
    array=new char[1];
}
CharArray(char *str) {
    array=new char[strlen(str)];
    strcpy(array, str);
}
CharArray(const CharArray amp;a) {
    array=new char[strlen(a.array)];
    strcpy(array, a.array);
}

//Деструктор
~CharArray() {
    delete [] array;
    //cout << "Сработал деструктор!" << endl;
}

//Остальные методы
//Выводит на экран содержимое массива
void ShowArray();
//Ввод данных в массив
void EnterString();
//Вывод информации о массиве
void InfoAboutArray();
int SayLength();
CharArray operator (CharArray amp;secondArray) const;
//CharArrayamp; operator=(const CharArray amp;a);
CharArrayamp; operator=(const char *a);
//Делаем большие буквы мальнькими и наоборот
void UpperCaseToLowerAndLowerCaseToUpper();
//Делаем маленькие буквы большие
void AllUpperCase();
//Делаем большие буквы маленькими
void AllLowerCase();

//Перегрузка операторов new и delete
void* operator new(size_t size);
void operator delete(void *p);

void* operator new[](size_t size);
void operator delete[](void *p);
};
  

Вот мой основной:

 int main(int argc, const char * argv[]) {
char m[16]="Hello, World!!!";
CharArray *m1;
cout << "Динамическое создание экземпляра класса, его инициализация строкой "Hello, World!!!" и вывод содержимого экземпляра на экран:" << endl;
m1=new CharArray(m);
m1->ShowArray();
cout << "Создание динамической копии экземпляра класса" << endl;
CharArray *m2;
m2=m1;
cout << "Вывод содержимого копии экземпляра на экран:" << endl;
m2->ShowArray();
delete m1;
delete m2;
return 0;
}
  

Как решить эту проблему?

Комментарии:

1. используйте std::vector или std::string

2. в ваших конструкторах вы недостаточно выделяете: array=new char[strlen(str) 1] должно использоваться вместо array=new char[strlen(str)] раньше strcpy .

3. почему вы динамически выделяете объекты, которые динамически выделяют массив в своем конструкторе? По крайней мере, ваш основной, который вы могли бы сохранить свободным от new и delete

4. Хорошее эмпирическое правило: количество new delete операторов и должно совпадать. (2 раза new -> 2 раза delete и т. Д.)

5. Вам не мешало бы ознакомиться с интеллектуальными указателями, стандартными контейнерами (например, vector), raii и современным C в целом.

Ответ №1:

Оператор в вашем основном:

 m2=m1;
  

поскольку m2 и m1 являются указателями, он назначит адрес в m1 into m2 .

Это не так, но когда вы:

 delete m1;
delete m2;
  

Первый оператор уничтожит память, а второй оператор попытается уничтожить ту же память (потому что ваши указатели одинаковы).

Существует проблема с владением: при m1 освобождении его владения вы должны установить для него значение null ( m1 = nullptr ).

Вот почему ваш код выдает эту ошибку. В любом случае в вашем коде есть другие ошибки с памятью (как вы можете видеть в других ответах или комментариях).

Комментарии:

1. Итак, и как я могу создать динамическую копию объекта моего класса и уничтожить объект и его копию?

2. m2 = m1 скопирует указатели. *m2 = *m1 скопирует указанный объект. Обратите внимание, что m2 и m1 должен быть правильно инициализирован, и вы должны определить подходящий operator= для вас класс.

Ответ №2:

array=new char[strlen(str)]; неверно; вам нужно array=new char[strlen(str) 1];

То же самое справедливо для array=new char[strlen(a.array)];

Переменные m1 и m2 не имеют типа CharArray ; они имеют тип указателя на CharArray ; поэтому, когда вы делаете m2=m1 ; (ну, Бьяджио уже ответил на это, поэтому я ухожу.)