C++ new & delete и string & functions
На предыдущий вопрос был дан четкий ответ, но я обнаружил еще одну проблему.
Что, если я сделаю:
char *test(int ran){
char *ret = new char[ran];
// process...
return ret;
}
А затем запустите его:
for(int i = 0; i < 100000000; i++){
string str = test(rand()%10000000+10000000);
// process...
// no need to delete str anymore? string destructor does it for me here?
}
Итак, после преобразования символа* в строку мне больше не нужно беспокоиться об удалении?
Edit: как ответ, я должен delete[]
каждый вызов new[]
, но в моем случае это невозможно, так как указатель потерялся, поэтому вопрос: Как правильно преобразовать char в строку?
5 ответов:
Здесь вы не преобразуете
Как правило, для каждогоchar*
в[std::]string
, а копируетеchar*
в[std::]string
.new
должно бытьdelete
.В этом случае вам нужно будет сохранить копию указателя и
delete
его, когда вы закончите:char* temp = test(rand()%10000000+10000000); string str = temp; delete[] temp;
Вы, кажется, находитесь под впечатлением, что передача
char*
в строку std:: передает право собственности на выделенную память. На самом деле он просто делает копию.Самый простой способ решить эту проблему-просто использовать строку std::во всей функции и возвращать ее напрямую.
std::string test(int ran){ std::string ret; ret.resize(ran - 1); // If accessing by individual character, or not if using the entire string at once. // process... (omit adding the null terminator) return ret; }
Да, да, это так.
Если вы используете linux / os x, посмотрите на что-то вроде valgrind , что может помочь вам с проблемами памяти
Вы можете изменить свою тестовую функцию так, чтобы она возвращала
string
вместоchar *
, таким образом, вы можетеdelete [] ret
в тестовой функции.Или вы можете просто использовать строку в тесте, а также и не беспокоиться о создании / удалении.
Вы должны вызывать
delete
для каждогоnew
, иначе произойдет утечка памяти. В случае, когда вы показали, что вы отбрасываете указатель, если вы должны оставить функцию как возвращающуюchar*
, то вам нужно будет использовать две строки для созданияstd::string
, чтобы вы могли сохранить копиюchar*
вdelete
.Лучшим решением было бы переписать вашу функцию
test()
, чтобы вернутьstd::string
напрямую.
Вам нужно сделать что-то вроде этого:
for(int i = 0; i < 100000000; i++){ int length = rand()%10000000+10000000; char* tmp = test(length); string str(tmp); delete[length] tmp; }
Это удаляет выделенный массив символов должным образом.
Кстати, вы всегда должны завершать строку нулем, если создаете ее таким образом (т. е. внутри функции
test
), в противном случае некоторые функции могут легко "запутаться" и обработать данные за вашей строкой как ее часть, что в лучшем случае приведет к сбою вашего приложения, а в худшем-к беззвучному переполнению буфера, ведущему к неопределенному поведению в более поздний момент, что является недопустимым. самый страшный отладочный кошмар... ;)