Хорошо на предыдущий вопрос ответили ясно, но я узнал другую проблему.
Что, если я делаю:
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?
}
Таким образом, после преобразования символа* для строкового представления я не должен больше волноваться об удалении?
Править: Как отвечено, я имею к delete[]
каждый new[]
звоните, но на моем случае не возможный, так как указатель потерялся, таким образом, вопрос: как я преобразовываю символ для строкового представления правильно?
Здесь вы не преобразуете char*
в [std::]string
, а копируете char*
в [std::]string
.
Как правило, для каждого new
должно быть delete
.
В этом случае вам нужно будет сохранить копию указателя и удалить
его, когда вы закончите:
char* temp = test(rand()%10000000+10000000);
string str = temp;
delete[] temp;
Похоже, вы впечатлены тем, что передаете char *
в std :: string передает право владения выделенной памятью. Фактически он просто делает копию.
Самый простой способ решить эту проблему - просто использовать std :: string во всей функции и вернуть ее напрямую.
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;
}
Вам нужно сделать что-то вроде этого:
for(int i = 0; i < 100000000; i++){
int length = rand()%10000000+10000000;
char* tmp = test(length);
string str(tmp);
delete[length] tmp;
}
Это правильно удаляет выделенный массив символов.
Между прочим, вы всегда должны завершать строку нулем, если вы создаете ее таким образом (т.е. внутри функции test
), иначе некоторые функции могут легко «запутаться» и обработать данные за вашей строкой. как часть этого, что в лучшем случае приводит к сбою вашего приложения, а в худшем - к созданию молчаливого переполнения буфера, ведущего к неопределенному поведению на более позднем этапе, что является последним кошмаром отладки ...;)
Да, да, можно.
Если вы используете linux/os x, посмотрите что-нибудь вроде valgrind, который может помочь вам с проблемами памяти
Вы можете изменить вашу тестовую функцию так, чтобы она возвращала string
вместо char *
, таким образом вы можете удалить [] ret
в тестовой функции.
ИЛИ вы можете просто использовать строку в test и не беспокоиться о new/delete.
Вы должны вызывать delete
для каждого new
, в противном случае произойдет утечка памяти. В случае, который вы показали, что вы выбрасываете указатель, если вы должны оставить функцию как возвращающую char *
, тогда вам нужно будет использовать две строки для создания std :: string
, чтобы вы могли сохранить копию char *
до delete
.
Лучшим решением было бы переписать вашу функцию test ()
так, чтобы она возвращала напрямую std :: string
.