std :: vector - как освободить память элементов char * в векторе?

Рассмотрим следующие коды C ++:

using namespace std;
vector<char*> aCharPointerRow;
aCharPointerRow.push_back("String_11");
aCharPointerRow.push_back("String_12");
aCharPointerRow.push_back("String_13");
for (int i=0; i<aCharPointerRow.size(); i++)  {
   cout << aCharPointerRow[i] << ",";
}
aCharPointerRow.clear();

После строки aCharPointerRow.clear(); все элементы указателя символа в aCharPointerRow должны быть удалены.

Есть ли утечка памяти в приведенном выше коде C ++? Нужно ли мне явно освобождать память, выделенную для строк char *? Если да, то как?

Спасибо за любое предложение.


person user1129812    schedule 13.03.2012    source источник
comment
Вы обрабатываете свои распределения, тогда vector будет обрабатывать свои собственные распределения.   -  person jalf    schedule 13.03.2012
comment
Это должно быть vector<const char*>. Указатель char* допускает модификацию, но "String_11" является строковым литералом и, следовательно, const.   -  person MSalters    schedule 13.03.2012


Ответы (4)


Есть ли утечка памяти в приведенном выше коде C ++?
Утечки памяти нет.

Поскольку вы никогда не использовали new, вам не нужно вызывать delete. Вам нужно только освободить динамическую память, если она была выделена в первую очередь.

Обратите внимание, что в идеале вы должны использовать вектор std::string.

std::vector<std::string> str;
str.push_back("String_11");
str.push_back("String_12");
str.push_back("String_13");

Вы можете использовать std :: string.c_str (), если вы необходимо получить базовый указатель на символ (char *), который многие C api ожидают в качестве параметра.

person Alok Save    schedule 13.03.2012

Вы вводите свои векторные строковые литералы (строки в "..."). Они не выделяются вами. Они предоставляются вам компилятором / средой выполнения C ++, и у них есть время жизни, равное времени жизни приложения, поэтому вы не можете / не должны их освобождать.

См., Например, Объем (строковых) литералов

Обратите внимание, что все, что я вам сказал, было основано на том факте, что вы используете строковые литералы. Если вам нужно выделить память для ваших строк, вам придется использовать некоторые автоматические освободители, такие как std::unique_ptr (из C ++ 11) или boost::unique_ptr или boost::shared_ptr (из Boost), или лучше использовать класс std::string, как предлагает Als

person xanatos    schedule 13.03.2012
comment
Почему бы просто не использовать вместо этого std::string? - person Alok Save; 13.03.2012
comment
@Als or better use the std::string class as suggested by Als - person xanatos; 13.03.2012
comment
@Als И в конце я хотел показать OP богатство автопоисков. Если он действительно интересуется C ++, они ему понадобятся ... - person xanatos; 13.03.2012
comment
Достаточно честно, я не замечаю этого "Мой плохой". - person Alok Save; 13.03.2012
comment
@xanatos Спасибо за ваши предложения. Я знаю о существовании умных указателей. Я новичок в C ++ и хочу прояснить концепции std :: vector. - person user1129812; 13.03.2012

В образце нет утечки, поскольку указатель, который вы указываете, не относится к динамической памяти.

Но это также плохо написанный код: строковые литералы постоянны, но C ++ позволяет ссылаться на них как на char *, чтобы сохранить обратную совместимость библиотеки C. Если вы собираетесь ссылаться на строковые литералы, вам лучше использовать const char* вместо char* (в случае попытки их изменения вы получите ошибку компилятора, а не исключение времени выполнения)

Еще одна плохая вещь здесь заключается в том, что в более обширном коде вы рано или поздно теряете контроль над тем, какие символы char * эффективно хранятся в векторе: предоставляются ли они всегда как строковые литералы или они также могут быть выделены другим способом динамический символ [] ?? И кто отвечает за их распределение / освобождение?

std :: vector ничего не говорит об этом, и если вы находитесь в положении, в котором вы не можете дать четкий ответ на приведенные выше вопросы (каждый const char* указанный буфер может либо существовать вне области существования вектора, либо нет), вам, вероятно, лучше использовать std::vector<std::string>, и обрабатывать строки как «значения» (а не объекты, на которые есть ссылки), позволяя классу строк выполнять грязную работу.

person Emilio Garavaglia    schedule 13.03.2012

Утечки нет. Пока вы не копируете эти строки, вам не нужно их явно удалять или освобождать ().

person Tomas Andrle    schedule 13.03.2012