#c #g #std #stdstring
Вопрос:
Я новичок в C , и я играл с его стандартной библиотекой регулярных выражений. Я сделал это доказательство функции поиска концепции на основе следующей ссылки. https://en.cppreference.com/w/cpp/regex/regex_iterator
Этот код отлично компилируется и выполняется, как и ожидалось, но, оглядываясь назад, я вижу пару мест, которые меня беспокоят, которые могут вызвать некоторую утечку памяти.
Как вы обрабатываете возвращаемое значение строки из вызова библиотеки? Копируете ли вы их в свой собственный строковый объект, созданный new
? Или вы относитесь к ним как к ценностям и никогда не беспокоитесь о выделении памяти?
Я знаю make_unique
, и make_shared
это отличные варианты для изучения, но мне неудобно их использовать, в то время как мое понимание структуры управления памятью c (например, где вызывается деструктор и т. Д.) Все еще шаткое.
#include <iostream>
#include <string>
#include <regex>
#include <vector>
//a proof of concept function that returns regex match strings
std::vector<std::string> return_matches(std::string str){
std::regex reg("[0-9] ");
std::vector<std::string> resu<
auto i = std::sregex_iterator(str.begin(), str.end(), reg);
auto str_end = std::sregex_iterator();
for(i; i != str_end; i ){
std::smatch match = *i;
result.push_back(match.str());
//string returned from match.str() will be shallow copied into the result array
//but at the same time, the string seems like to be going out of the scope,
//does that mean its destructor is called and its internal (heap) memory
//gets freed?
}
return resu<
//Same thing here, will the destructor be called for the vector object,
//leading to a memory leak
}
int main(){
std::string input = "hello 123 afsdha 554 asda 12 721";
auto result = return_matches(input);
//printing the result
for(int i = 0; i < result.size(); i ){
std::cout << result[i] << std::endl;
}
}
Ответ №1:
Когда я должен удалить строку std::, возвращенную из std::smatch внутри итератора регулярных выражений, если вообще?
Вы удаляете только указатели. Более конкретно, вы удаляете указатели, которые были возвращены выражением (без размещения) new
.
match.str()
не возвращает указатель. Он возвращает экземпляр std::string
. Вам это не нужно, и вы не можете удалить std::string
объект.
Как вы обрабатываете возвращаемое значение строки из вызова библиотеки?
Это временный объект. Независимо от того, как вы с этим справляетесь, временный объект уничтожается автоматически. Нет никакого риска утечки памяти.
Вы копируете их в свою собственную строку …
Конечно, вы можете это сделать, если хотите сохранить строку на потом.
… что создано новым?
Нет. Таким образом, происходит утечка памяти. Вряд ли когда-либо возникала необходимость в использовании new
и еще реже возникала необходимость в использовании new
для создания std::string
экземпляра.
Или вы относитесь к ним как к ценностям и никогда не беспокоитесь о выделении памяти?
ДА. Относитесь к ценностям как к ценностям.
//does that mean its destructor is called
ДА. Временный объект уничтожается в конце содержащего его полного выражения.
//and its internal (heap) memory gets freed?
Если какая-либо память была выделена std::string
, она позаботится об ее освобождении.
//Same thing here, will the destructor be called for the vector object,
Да, объекты с автоматическим сроком хранения автоматически уничтожаются в конце области, в которой они объявлены.
//leading to a memory leak
Нет, совсем наоборот. Поскольку деструктор освобождает память, утечки нет.
Комментарии:
1.
It's a temporary object. Regardless of the way you deal with it, the temporary object is destroyed automatically. There's no risk of memory leak.
Что происходит с блоком памяти, на который ссылается объект? Разве его ссылка не копируется в новый объект? Если этот блок памяти освобождается внутри деструктора, не приведет ли это к двойному освобождению, когда скопированный объект тоже будет уничтожен?2. @Y. Yoshii Конструктор перемещения
std::string
сделает так, чтобы старая строка больше не ссылалась на память.3. С конструктором перемещения на картинке все это теперь имеет гораздо больше смысла. Большое вам спасибо!