Я кодирую некоторый критически важный код, который я должен убедиться, что он абсолютно свободен от утечек памяти. Я написал небольшую функцию, которая позволяет мне извлекать память во время выполнения, и я делаю измерения до и после выполнения некоторого кода (который должен быть утечкой), чтобы увидеть, остается ли использование памяти на том же уровне.Управление памятью в C++ STL в контейнерах
При отладке фрагмента кода, который «утечка», я, наконец, обнаружил, что виновником является векторный контейнер.
Минимальный код, который воспроизводит то, что я вижу, заключается в следующем:
vector<char*>* v = new vector<char*>();
int n = 1024*1024;
while (n--)
{
v->push_back(new char[256]()); // A
}
for (vector<char*>::iterator it=v->begin() ; it!=v->end() ; ++it)
{
delete[] (*it);
}
delete v;
Если вы бежите, что код (инвалидизирующую оптимизация компилятора, конечно, -O0
) и положить некоторую ловушку в конце, чтобы программа не выйдет (например, cin.ignore();
), вы увидите, что ваша программа должна использовать около 20 Мб или около того памяти.
Я хотел бы понять, почему это происходит. Есть строка, которую я обозначил A
, где, если вы выделите большой массив символов, вы увидите, что «оставшаяся» память в конце тоже больше. Я бы не назвал это утечкой как таковой, потому что, по-видимому, память могла быть повторно использована, если я выделяю и заполняю другой контейнер STL, но все же я ожидал, что эта память полностью освободится, когда код закончится.
Может кто-то пролить свет на то, почему эта память все еще используется? И как я могу «освободить» его по-настоящему?
Некоторые подробности о моей среде компилятора:
Using clang++: Apple LLVM version 6.0 (clang-600.0.51) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix
Compiling with: g++ -std=c++11 -g -Wall -Wextra -Wpedantic -O0 main.cc -o main.out
Почему вы хотите использовать вектор вместо вектора >!? –
Borgleader
Я просто использую этот символ * для выделения произвольного количества памяти. На практике вы можете использовать любой тип там, и вы все равно будете наблюдать это поведение. – almosnow
Вы, кажется, ожидаете, что диспетчер памяти фактически освободит память от вашего процесса только потому, что вы его освободили, но это не так, как обычно работает. Во всяком случае, это просто виртуальная память, поэтому, пока ваш процесс не использует его, он не занимает никакой ОЗУ. И, как вы сказали, если вы попросите больше памяти, чтобы память была повторно использована. – ooga