Вот код:Удаление массива объектов
class A {
private:
int *anArr;
int id;
public:
A() {
id = 0;
anArr = new int[10];
}
A(int i) {
id = i;
anArr = new int[10];
}
~A() {
delete[] anArr;
std::cout << "Class A id : " << id << " destructor" << std::endl;
}
};
class B {
private:
A *anArr;
public:
B() {
anArr = new A[10];
}
~B() {
std::cout << "Class B destructor" << std::endl;
delete[] anArr;
}
void changeAnElement() {
anArr[2] = A(1);
anArr[2] = A(2);
}
};
int main()
{
B b;
b.changeAnElement();
return 0;
}
Выход:
Class A id : 1 destructor
Class A id : 2 destructor
Class B destructor
Class A id : 0 destructor
Class A id : 0 destructor
Class A id : 0 destructor
Class A id : 0 destructor
Class A id : 0 destructor
Class A id : 0 destructor
Class A id : 0 destructor
// Gives heap error here
Так что, если я не ошибаюсь, когда я изменить элемент массива объекта он не вызывает деструктор , Мой первый вопрос: что происходит со старым объектом в измененном индексе? Является ли массив в нем утечкой? Я думал, что мне нужно сам вызвать деструктор, чтобы предотвратить утечку памяти, но он дает ошибку кучи. Второй вопрос: я получаю ошибку кучи (Expression: _CrtlsValidHeapPointer(block)
) при вызове деструктора измененного объекта. Я понятия не имею, почему это прекрасно работает для созданных в конструкторе. Спасибо!
Обратите внимание: если вы выполняете ручное управление памятью в классе, вам необходимо следовать правилу 3 или 5. – NathanOliver
Я бы предположил, что 'anArr [0] = A (1)' эквивалентен 'anArr [0] .operator = (A (1)) ', который построил бы новый' A' с 'id = 1', вызовет конструктор копирования' anArr [0] 'с этим' A, id = 1', затем уничтожить 'A, id = 1'. Реализация по умолчанию для 'A :: operator =' не будет управлять вашей памятью для вас, поэтому вы просачиваетесь. Решение: Внесите конструктор копирования или используйте 'std :: vector' /' std :: array' – lcs
@NathanOliver спасибо, я никогда не слышал о них. –