Когда я должен удалить строку std::, возвращенную из std::smatch внутри итератора регулярных выражений, если вообще?

#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. С конструктором перемещения на картинке все это теперь имеет гораздо больше смысла. Большое вам спасибо!