Я создаю std :: вектор MyClass1. Я не использую никаких указателей на этот класс, поэтому я хочу знать: это мой способ использования безопасности std :: vector или у меня проблема с утечками памяти здесь?
Почему я спрашиваю? Я добавил constuctor и destructor для MyClass1, и никогда не звонят. Что мой код:
class MyClass1 {
public:
MyClass1() {
printf( "constructor\n" );
}
~MyClass1() {
printf( "destructor\n" );
}
int var1;
std::string str;
};
std::vector< MyClass1 > testArr;
MyClass1 gr1;
gr1.var1 = 111;
testArr.push_back( gr1 );
gr1.var1 = 122;
testArr.push_back( gr1 );
printf( "testArr.at( 1 ).var1 = %i\n", testArr.at( 1 ).var1 );
Он вызывает конструктор, но он никогда не вызывает деструктор.
Это утечка.
вектор управляет собственной памятью, поэтому сам не просачивается. И вы используете локальные экземпляры MyClass и копируете их, что также не приведет к утечке. Наконец, член строки MyClass управляет своей памятью так же, как вектор, поэтому никаких утечек нет.
Если вы беспокоитесь об утечках, просто избегайте использования raw new/delete и используйте интеллектуальные указатели вместо этого, используйте стандартные контейнеры, такие как вы здесь, и не выделяйте память, если вам действительно не нужно.
Чтобы устранить недостатки вызовов конструктора/деструктора... то, что вы, вероятно, видите, является эффектом оптимизации компилятора. Повторите попытку с полной оптимизацией и посмотрите, что вызвано.
Редактировать:
Я просто запускаю этот код...
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
class MyClass1 {
public:
MyClass1() {
printf( "constructor\n" );
}
~MyClass1() {
printf( "destructor\n" );
}
int var1;
string str;
};
int main()
{
vector< MyClass1 > testArr;
MyClass1 gr1;
gr1.var1 = 111;
testArr.push_back( gr1 );
gr1.var1 = 122;
testArr.push_back( gr1 );
printf( "testArr.at( 1 ).var1 = %i\n", testArr.at( 1 ).var1 );
return 0;
}
... с GCC 4.7.2, оптимизация выключена и получила этот результат:
constructor
destructor
testArr.at( 1 ).var1 = 122
destructor
destructor
destructor
Код, который вы указали, не содержит утечек. testArr
вызывается только тогда, когда testArr
деструктор testArr
или вы вызываете testArr.clear()
.
В примере gr1
копируется или перемещается (если возможно) в вектор. Деструктор gr1
когда gr1
выходит за пределы области действия, или элементы в векторе удаляются. Ничего из этого не происходит в примере кода, что означает, что деструктор не будет вызван.
Когда метод выходит (не показано в коде), вы должны увидеть, что деструктор вызывается три раза. Дважды для элементов в vector
и один раз для gr1
.