Новый C++ и удаляет и представляет в виде строки, и функционирует

Хорошо на предыдущий вопрос ответили ясно, но я узнал другую проблему.

Что, если я делаю:

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[] звоните, но на моем случае не возможный, так как указатель потерялся, таким образом, вопрос: как я преобразовываю символ для строкового представления правильно?

6
задан Community 23 May 2017 в 12:06
поделиться

5 ответов

Здесь вы не преобразуете char* в [std::]string, а копируете char* в [std::]string.

Как правило, для каждого new должно быть delete.

В этом случае вам нужно будет сохранить копию указателя и удалить его, когда вы закончите:

char* temp = test(rand()%10000000+10000000);
string str = temp;
delete[] temp;
9
ответ дан 8 December 2019 в 12:57
поделиться

Похоже, вы впечатлены тем, что передаете 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; 
} 
3
ответ дан 8 December 2019 в 12:57
поделиться

Вам нужно сделать что-то вроде этого:

for(int i = 0; i < 100000000; i++){ 
   int length = rand()%10000000+10000000;
   char* tmp = test(length); 
   string str(tmp);
   delete[length] tmp;
}

Это правильно удаляет выделенный массив символов.

Между прочим, вы всегда должны завершать строку нулем, если вы создаете ее таким образом (т.е. внутри функции test ), иначе некоторые функции могут легко «запутаться» и обработать данные за вашей строкой. как часть этого, что в лучшем случае приводит к сбою вашего приложения, а в худшем - к созданию молчаливого переполнения буфера, ведущего к неопределенному поведению на более позднем этапе, что является последним кошмаром отладки ...;)

2
ответ дан 8 December 2019 в 12:57
поделиться

Да, да, можно.

Если вы используете linux/os x, посмотрите что-нибудь вроде valgrind, который может помочь вам с проблемами памяти

Вы можете изменить вашу тестовую функцию так, чтобы она возвращала string вместо char *, таким образом вы можете удалить [] ret в тестовой функции.

ИЛИ вы можете просто использовать строку в test и не беспокоиться о new/delete.

2
ответ дан 8 December 2019 в 12:57
поделиться

Вы должны вызывать delete для каждого new , в противном случае произойдет утечка памяти. В случае, который вы показали, что вы выбрасываете указатель, если вы должны оставить функцию как возвращающую char * , тогда вам нужно будет использовать две строки для создания std :: string , чтобы вы могли сохранить копию char * до delete .

Лучшим решением было бы переписать вашу функцию test () так, чтобы она возвращала напрямую std :: string .

2
ответ дан 8 December 2019 в 12:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: