2010-11-03 2 views
8

Я использую STL string в приложении моего, и я недавно тестировал его на утечки памяти, и я заметил, что многие мои строки не были должным образом освобождены до конца программы.Утечки памяти строк C/C++?

я тестировал следующий код (не дословно) с одной из строк:

const string* cppString = &obj->objString; 
const char* cString = cppString->c_str(); 
delete obj; 

После этого я поставил брейк-пойнт и заметил, что, в то время как string что cppString не указал больше не существует, cString все еще указывал на строку стиля C, которая, безусловно, была той, которая не была освобождена в конце.

Я пропустил что-то в терминах того, как работают строки C/C++? Как я могу получить представление C строки, которую нужно освободить?

EDIT: Дополнительная информация. Мой класс obj имеет тип Dialog, который наследует Popup. Я думал, что это могло быть, поскольку, когда я удаляю obj, я рассматриваю его как Popup*, но я попробовал его в небольшой отдельной программе, и удаление в качестве родительского класса правильно удаляет дочерние переменные-члены (что имеет смысл , конечно).

Я использовал трассировку утечки памяти в VS, и это показывает, что строка, которая закончилась утечкой, была той, которая была создана, когда я сделал Dialog и установил objString в строку, переданную как ссылка на конструктор.

Спасибо,
Jengerer

+0

(К сожалению, мой предыдущий комментарий был связан с ошибкой при чтении приоритета оператора). Я думаю, вам нужно показать больше кода. Не видя определения 'obj' и того, как его выделить, трудно предположить, будет ли' obj-> objString' корректно освобожден. –

+0

Это похоже на беспорядок здесь, поэтому я собираюсь обновить OP своим комментарием. – Jengerer

+1

Имеет ли 'Popup' виртуальный деструктор? –

ответ

8

То, что вы видите, это неопределенное поведение -это на самом деле не утечка памяти. Память для строки C имеет освобождена (по крайней мере, насколько это касается вас), но данные там по-прежнему технически доступны. Когда вы освобождаете память, память обычно не стирается, поэтому данные там часто остаются вокруг, пока память не будет повторно использоваться путем последующего выделения.

Чтение данных после того, как оно было освобождено, является неопределенным поведением: вы можете получить данные, которые были до его освобождения, вы можете получить данные об мусоре, вы можете свернуть свою программу или даже стереть жесткий диск (хотя это не так скорее всего).

Пока объект std::string должным образом освобожден, любая память, используемая для его строкового представления C, также будет освобождена. Тебе не нужно об этом беспокоиться.


EDIT: На самом деле оказывается, что ваш объект не был получать валяной разрушен, потому что родительский класс Popup не иметь виртуальный деструктор. В результате деструктор для подкласса Dialog не вызывался, поэтому деструктор для экземпляра std::string не вызывался.

+0

Это имело бы смысл, но я использовал процедуру обнаружения утечки памяти Visual Studio (которая в основном следует всем вызовам «malloc» и «free»), и когда я удалял информацию об утечке памяти в конце программы, эта строка, среди аналогично расположенные, отображаются как нераспределенные. – Jengerer

3

Проблема, скорее всего, не в std::string, а в obj (независимо от того, что есть). Обратите внимание, что вы удалили obj, а не cppString.Я предполагаю, что obj не хранит objString в классе интеллектуальных указателей, и он не удаляет objString в своем деструкторе, и, следовательно, у вас есть эта утечка.

+0

'objString' - это регулярная строка, а не указатель, поэтому она должна автоматически удаляться деструктором по умолчанию, нет? – Jengerer

+0

@Jengerer, вы назначили из objString тип «const string *», а не наберите «const string», поэтому он должен быть типом указателя, если вы не поделились с нами другим кодом. –

+0

Я имел в виду, что в классе объектов 'objString' является строковым типом, а не указателем. Когда я назначил его 'const string *', я сделал '& obj-> objString', поэтому я использовал оператор & для получения адреса. – Jengerer

Смежные вопросы