Строка C ++ переназначена, старая строка правильно освобождена? - PullRequest
4 голосов
/ 30 августа 2010

У меня есть класс C ++ с членом, который является строкой, что-то вроде:

class Phone {
string name;

void foo()
  {
    name = string("new_name");
  }
}

Теперь внутри функции "foo" я переназначаю строку на "new_name". Мой вопрос:

  • Что происходит со старой пустой строкой? Правильно ли это "освобождено"? Он все еще занимает память?
  • Теперь я инициализирую строку в конструкторе Phone в string ("old_name"). Это тот же случай, что и с пустой строкой раньше? Что здесь происходит со старой строкой "old_name"?

Ответы [ 4 ]

7 голосов
/ 30 августа 2010

Да, std::string управляет памятью для вас. (Это одна из причин его существования!) Как это происходит, это деталь реализации (например, он может использовать копирование при записи, подсчет ссылок или глубокую семантику копирования), но по большей части std::string всегда правильно освобождайте память, если она больше не нужна.

Конечно, это предполагает, что нет ошибок в реализации операторов присваивания или деструктора std::string (что верно для всех классов, которые реализуют оператор / деструктор присваивания не по умолчанию).

3 голосов
/ 30 августа 2010

Если это std::string, о котором мы говорим, тогда все правильно освобождено.

Однако, что именно происходит под капотом, зависит от реализации. Несколько реализаций std :: string используют некоторую форму подсчета ссылок, поэтому она зависит от реализации.

Также обратите внимание, что ваш код работает так же, как:

name = "new_name";

... и даже более явно:

name.assign( "new_name" );
1 голос
/ 30 августа 2010

Что происходит со старой пустой строкой? Правильно ли это "освобождено"? Это все еще занимает память?

Как правило, он не должен занимать много памяти (если вы его не инициализировали). При присваивании строка может перераспределиться в. Что вы делаете, это:

  • Создание временного строкового объекта, который освобождается после завершения присваивания в ;
  • Скопируйте конструкцию новой строки, используя это временное значение, а затем установите для нее исходную переменную name.

Любое перераспределение памяти правильно освободит исходную память. Примечание. Компилятор может оптимизировать или не оптимизировать некоторые этапы в зависимости от ваших настроек.

Теперь я инициализирую строку в конструктор телефона для строка ( "предыдущее_имя"). Это то же самое случай как с пустой строкой раньше? Что здесь происходит со старой строкой "Old_name"?

Зависит. Если вы используете списки инициализаторов, то нет, это не то же самое. Там нет назначения; вызывается только конструктор копирования.

1 голос
/ 30 августа 2010
  • Если оператор присваивания написан правильно, будет вызван деструктор.
  • Если деструктор записан правильно, используемая память освобождается.
...