Я использую это в пустоте:
unsigned char *nEncodedBytes = NULL;
nEncodedBytes = new unsigned char[m_lLenCompressedBytes];
short *shrtDecoded = NULL;
shrtDecoded = new short[iCountDecodedShorts];
short *m_ShortOut;
m_ShortOut = (short*)malloc(( 960*6)*sizeof(short));
unsigned char *m_DataBytes;
m_DataBytes = (unsigned char*)calloc((960*6),sizeof(char));
Когда я закончил, я освобожу память, используя
delete (nEncodedBytes);
delete (shrtDecoded);
free(m_DataBytes);
free(m_ShortOut);
Это прекрасно? Я не уверен, почему я использовал delete в одном месте и свободно в другом. Я скопировал свой код.
Есть ли утечка памяти?
Спасибо.
Вы используете free
когда используете malloc
. По всей вероятности, вы не должны использовать malloc
вообще в C++; это способ сделать что-то и только редко хотел в C++.
Вы используете delete
при назначении new
. new
вызовы конструктора, а также выделение памяти, а также delete
вызовов деструктора, а также освобождение памяти. Это, таким образом, объекты, ориентированные на C++. Однако есть морщина. Поскольку реализация C++ не знает, ссылается ли указатель на массив или на один объект, если вы выделяете массив (например, nEncodedBytes = new unsigned char[m_lLenCompressedBytes];
), тогда вы должны использовать delete[]
вместо delete
освободить его.
Имейте в виду, что вы не можете вызвать delete[]
только означает, что вы вызовете деструктор только для первого объекта в массиве, поэтому в этом конкретном случае не должно быть разницы в результате между вызовом delete[]
и вызовом delete
поскольку char
имеет нет деструктора.
Я не вижу утечки памяти в вашем коде, но так как вы не разместили весь свой код, мы не можем сказать.
Вы должны использовать
delete [] nEncodedBytes;
delete [] shrtDecoded;
поскольку вы удаляете массивы.
free
delete
или delete
delete
для new(]
'ed массивов является UB и может привести к утечкам (это имеет место в ряде реализаций). Но уверен, что ответ можно улучшить.
Не смешивайте malloc
и new
(сначала из-за стилистических причин, а затем потому, что вы никогда не должны delete
память malloc
-ed или free
new
зону -ed). Рассмотрим использование стандартных контейнеров C++. Вам даже не нужно явно выделять память (библиотека сделает это для вас). Вы можете ввести код
std::vector<char> nEncodedBytes;
nEncodedBytes.resize(encodedbyteslen);
В Linux используйте valgrind для поиска утечек памяти. Кстати, вас может заинтересовать Boehm GC, возможно, используя его распределитель, как здесь.
BTW, при использовании себя malloc
вы всегда должны проверять его результат, по крайней мере, как
SomeType* ptr = malloc(sizeof(SomeType));
if (!ptr) { perror("malloc SomeType"); exit(EXIT_FAILURE); };
помните, что malloc
может потерпеть неудачу. Возможно, вы захотите ограничить доступную память (например, с помощью ulimit -m
в bash
в вашем терминале) для целей тестирования (например, чтобы сделать malloc
-or new
- сбой легче, чтобы вы достаточно хорошо справлялись с подобным отказом).
malloc
и new
нельзя смешивать. До тех пор, пока malloc
s сопоставляются со free
s, new
s сопоставляются с delete
s, а new[]
сопоставляются с delete[]
s.
Это прекрасно?
Не совсем. Есть пара проблем. Одно - ваше хлопотное использование free
- мы обратимся через минуту. Но во-первых, использование вами new[]
с delete
(non- []
) вызывает Undefined Behavior:
Здесь вы используете new []
:
nEncodedBytes = new unsigned char[m_lLenCompressedBytes];
И здесь вы используете delete
:
delete (nEncodedBytes);
Это должно быть:
delete [] nEncodedBytes;
Использование []
для new
с non- []
формой delete
вызывает Undefined Behavior. Теперь на самом деле все компиляторы и платформы, о которых я знаю, будут справляться с этим штрафом и делать то, что вы ожидаете в этом конкретном случае, - но вы никогда не должны полагаться на Undefined Behavior.
Теперь для вашего использования malloc
и free
:
Я не уверен, почему я использовал delete в одном месте и свободно в другом.
Вероятно, этого не должно быть. Здесь эмпирическое правило:
В C++ всегда используйте
new
иdelete
; никогда не используйтеmalloc
иfree
.
Да, есть исключения, но они в первую очередь редки, и, во-вторых, вы точно узнаете, когда появляются исключения. В примере, который вы разместили здесь, я не вижу причин, которые заставляют использовать malloc
и free
. Следовательно, вы не должны быть.
Вопреки убеждению (популярности?), Смешивание new
/delete
и malloc
/free
в одной программе C++ само по себе не вызывает Undefined Behavior или делает вашу программу иначе плохо сформированной. Вы можете это сделать, если вы сделаете это правильно. Но вы все равно не должны.
Есть ли утечка памяти?
Ну, так как вы вызвали Undefined Behavior, может быть. Неопределенное поведение означает, что все может случиться. Тем не менее, вы выделяете все, что вы выделили, в показанном коде. Поэтому, помимо UB, я не вижу утечки памяти.