Я написал тест, чтобы проверить, вызывались ли деструкторы перед перезаписывающим присваиванием для переменной стека, и я не могу найти никакого рационального объяснения результатов ...
Это мой тест (в режиме выпуска Visual C ++ 2008):
#include <iostream>
class C {
public:
char* ptr;
C(char p) { ptr = new char[100]; ptr[0] = p;}
~C() { std::cout << ptr[0] << ' '; delete [] ptr; }
};
int _tmain(int argc, _TCHAR* argv[])
{
{
C s('a');
s = C('b');
s = C('c');
s = C('d');
}
std::cin.get();
return 0;
}
Я ожидал получить либо «a b c d», если моя гипотеза была верна, либо просто «d», если ложь.
Вместо этого я получаю «b c d x». «X» изменяется в зависимости от того, сколько памяти выделено для ptr, что указывает на то, что он читает случайные значения кучи.
Я полагаю, что происходит (поправьте меня, если я ошибаюсь), что каждый вызов конструктора создает новое значение стека (давайте назовем их s1, s2, s3, s4), а затем присваивания оставляют s1.ptr перезаписанным s4.ptr. Затем s4 уничтожается сразу после копирования, но s1 (с висящим ptr) уничтожается при выходе из области действия, вызывая двойное удаление s4.ptr и не удаляя исходный s1.ptr.
Есть ли способ обойти это бесполезное поведение, которое не связано с использованием shared_ptrs?
изменить: заменить «удалить» на «удалить []»