C ++ Утечка памяти при освобождении *?

0

Я использую это в пустоте:

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 в одном месте и свободно в другом. Я скопировал свой код.

Есть ли утечка памяти?

Спасибо.

Теги:
memory-leaks

4 ответа

4
Лучший ответ

Вы используете free когда используете malloc. По всей вероятности, вы не должны использовать malloc вообще в C++; это способ сделать что-то и только редко хотел в C++.

Вы используете delete при назначении new. new вызовы конструктора, а также выделение памяти, а также delete вызовов деструктора, а также освобождение памяти. Это, таким образом, объекты, ориентированные на C++. Однако есть морщина. Поскольку реализация C++ не знает, ссылается ли указатель на массив или на один объект, если вы выделяете массив (например, nEncodedBytes = new unsigned char[m_lLenCompressedBytes];), тогда вы должны использовать delete[] вместо delete освободить его.

Имейте в виду, что вы не можете вызвать delete[] только означает, что вы вызовете деструктор только для первого объекта в массиве, поэтому в этом конкретном случае не должно быть разницы в результате между вызовом delete[] и вызовом delete поскольку char имеет нет деструктора.

Я не вижу утечки памяти в вашем коде, но так как вы не разместили весь свой код, мы не можем сказать.

  • 1
    Использование delete для указателя, выделенного с помощью new [], является неопределенным поведением. Идея, что он вызывает только один деструктор, может быть верной для одного конкретного компилятора, но это не гарантируется никаким стандартом.
2

Вы должны использовать

delete [] nEncodedBytes;
delete [] shrtDecoded;

поскольку вы удаляете массивы.

  • 0
    Хотя это действительно так, это не имеет значения для вопроса об утечке памяти или ответа на вопрос о free delete или delete
  • 0
    @JackAidley С этим можно поспорить. Вызов delete для new(] 'ed массивов является UB и может привести к утечкам (это имеет место в ряде реализаций). Но уверен, что ответ можно улучшить.
Показать ещё 3 комментария
2

Не смешивайте 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 - сбой легче, чтобы вы достаточно хорошо справлялись с подобным отказом).

  • 2
    Помимо соображений согласованности, нет технической причины, по которой malloc и new нельзя смешивать. До тех пор, пока malloc s сопоставляются со free s, new s сопоставляются с delete s, а new[] сопоставляются с delete[] s.
  • 0
    Я использовал вектор <short> shrtDecoded; shrtDecoded.resize (iCountDecodedShorts + 1); сейчас, но мне нужно передать их в функцию, которая ожидает "короткий *". Могу ли я использовать vector <short> в качестве аргумента? Я попытался передать shrtDecoded [0], но это не сработало.
Показать ещё 3 комментария
0

Это прекрасно?

Не совсем. Есть пара проблем. Одно - ваше хлопотное использование 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, я не вижу утечки памяти.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню