Подтвердить что ты не робот

Объект С++, созданный с новым, уничтоженным с помощью free(); Насколько это плохо?

Я работаю над модификацией относительно большой программы на С++, где, к сожалению, не всегда ясно, использовал ли кто-то до меня синтаксис C или С++ (это в отделе электротехники в университете, и мы, EE, всегда искушаем использовать C для всего, и, к сожалению, в этом случае люди могут с этим справиться).

Однако, если кто-то создает объект:

Packet* thePacket = new Packet();

Не имеет значения, уничтожен ли с помощью delete thePacket; или free(thePacket);?

Я понимаю, что delete вызывает деструктор, а free() - нет, но пакет не имеет деструктора. У меня ужасное время застряло в болоте управления памятью, и я думаю, что это может быть одной из многих проблем.

4b9b3361

Ответ 1

Да, это имеет значение. Для памяти, полученной с помощью new, вы должны использовать delete и использовать free для тех, которые получены из malloc. new и malloc могут использовать разные структуры данных внутри, чтобы отслеживать, что и где она выделяет память. Поэтому, чтобы освободить память, вы должны вызвать соответствующую функцию, которая знает об этих структурах данных. Однако, как правило, плохой идеей смешать эти два типа распределения памяти в куске кода.

Ответ 2

Если вы вызываете free(), деструктор не вызывается.

Кроме того, не гарантирует, что new и free работают в одной и той же куче.

Вы также можете переопределить new и delete для работы специально для определенного класса. Если вы это сделаете, но вызовите free() вместо пользовательского delete, то вы пропустите любое специальное поведение, которое вы написали в delete. (Но вы, вероятно, не задавали бы этот вопрос, если бы вы это сделали, потому что вы знали, какие поведенческие действия вам не хватает.)

Ответ 3

Packet имеет деструктор, даже если вы его явно не объявили. Он имеет деструктор по умолчанию. Деструктор по умолчанию, вероятно, на самом деле мало что делает, но вы не можете рассчитывать на то, что это так. Это до компилятора, что он делает.

new и malloc также могут иметь совершенно разные реализации. Например, delete всегда вызывается в контексте, где он имеет отличную информацию о размере структуры данных, которую он удаляет во время компиляции. free не обладает этой роскошью. Возможно, что распределитель, который использует new, может не хранить байты в начале области памяти, указав, сколько байтов он занимает. Это приведет к тому, что free сделает совершенно неправильную вещь и сбой вашей программы, освободив что-то выделенное с помощью new.

Лично, если заставить людей делать правильные вещи или самостоятельно исправлять код, я бы объявил свой собственный глобальный operator new, который назывался malloc, поэтому free определенно не сработает, хотя это будет по-прежнему не называйте деструктора, как правило, очень уродливым.

Ответ 4

Вы абсолютно правы, это НЕ правильно. Как вы сами сказали, бесплатно не назовете деструктора. Даже если пакет не имеет явного деструктора, он использует унаследованный.

Использование free объекта, созданного с помощью new, похоже на уничтожение только того, что достигнет мелкой копии. Глубокое разрушение НУЖДАЕТ функцию деструктора.

Кроме того, я не уверен, что объекты, созданные с помощью new(), находятся на одной карте памяти, такой как malloc() 'd memory. Думаю, они не гарантированы.

Ответ 5

Короче говоря, это так же плохо, как поведение undefined.

Это тихое объяснение.

C Standard ($ 7.20.3.2/2) - "Свободный функция вызывает пространство, на которое указывает по ptr, подлежащему освобождению, то есть, доступный для дальнейшего распределения. Если ptr - нулевой указатель, никакое действие имеет место. В противном случае, если аргумент не соответствует указателю раньше возвращаются calloc, malloc или realloc, или если пространство имеет был освобожден путем вызова бесплатного или realloc, поведение undefined."

Ответ 6

если кто-то создает объект:

Packet* thePacket = new Packet();

Не имеет значения, уничтожен ли с удалением пакет; или бесплатно (thePacket);

Да, это имеет значение. free (thePacket) будет ссылаться на Undefined Behavior, но delete thePacket не будет, и мы все знаем Undefined Поведение может иметь катастрофические последствия.