У меня есть следующая функция в С++
void func1()
{
char *p = "Test for memory leak";
}
Когда вызывается func1()
, где выделяется память для переменной? Будь то в стеке или в куче? Должен ли delete p;
вызываться явно?
У меня есть следующая функция в С++
void func1()
{
char *p = "Test for memory leak";
}
Когда вызывается func1()
, где выделяется память для переменной? Будь то в стеке или в куче? Должен ли delete p;
вызываться явно?
Нет, память выделяется только для указателя p
в стеке. Эта память автоматически освобождается, когда p
выходит за рамки. p
просто указывает на строку, которая хранится где-то в разделе вашей программы, доступном только для чтения. В идеале он должен быть определен как const char *p
. Если вы попытаетесь delete
сделать это, это будет неопределенное поведение. Как правило, вы можете помнить, что для каждого вызова new
должен быть вызов delete
char const *p
- принудительное использование указателя только для чтения - это хорошее поведение, поскольку оно отражает намерение указателя - быть доступным только для чтения.
- person PP.; 30.11.2009
Память для строкового литерала выделяется в статической памяти, и это выделение длится в течение всего времени работы программы. Вы не должны вызывать удаление - вызов удаления приведет к неопределенному поведению.
Операторы new и new[] используются для явного выделения памяти в куче в C++.
Правило:
1. вызывать delete
для каждого используемого new
оператора
2. вызывать delete[]
для каждого используемого new[]
оператора.
Остальное все идет в стек, и его не следует освобождать явно. Об этом позаботятся автоматически.
Следуйте этому правилу, и вы не ошибетесь.
Однако будьте осторожны, если вы используете new в цикле и используете удаление вне его. Это вызывает большие утечки памяти.
Лучшей практикой является использование интеллектуальных указателей, которые автоматически освобождают память для вас, когда указатель выходит за пределы области видимости. Библиотека Boost предлагает несколько хороших вариантов для того же. Подробнее об этом читайте здесь:http://www.boost.org/doc/libs/1_41_0/libs/smart_ptr/smart_ptr.htm
--Самрат Патил
Для того, чтобы точно знать, есть ли утечка, можно воспользоваться отладчиком. Мне нравится использовать deleaker. С его помощью вы можете узнать, в какой момент происходит утечка. А зная, где течь, легко устранить.
Утечек памяти нет вообще. Если вы посмотрите на скомпилированный код, строка Test for memory leak\0
на самом деле является частью исполняемой программы, и загрузчик скопирует ее в память во время выполнения. Операционная система очищает эту предварительно загруженную память после завершения программы.
Сама переменная *p
выделяется в стеке при вызове функции, а когда функция возвращает значение, указатель удаляется из стека.
Функция определяет указатель p
, который указывает на статически выделенную строку "Test for memory leak"
.
Ничто не выделяется динамически, поэтому ничего не нужно освобождать вручную.
Вы должны всегда связывать вызовы с new
и delete
. Когда что-то new
, это должно быть deleted
, и наоборот.
В вашем случае сама строка является статической и длится до тех пор, пока программа не завершится. А p
— это локальная переменная в стеке, и она существует до тех пор, пока функция не вернется.
Таким образом, оба они обрабатываются системой автоматически.
Строковые литералы обычно располагаются в текстовом сегменте исполняемого файла только для чтения. Вызов бесплатно/удалить их, вероятно, приведет к плохим последствиям.
delete
требуется для вызова памяти, выделенной с помощью new
(только для памяти, полученной из кучи).