В чем разница между new / delete и malloc / free?


Ответы:


466

новый / удаление

  • Выделить / освободить память
    1. Память, выделенная из «Free Store»
    2. Возвращает полностью типизированный указатель.
    3. new (стандартная версия) никогда не возвращает NULL (будет выдано при ошибке)
    4. Вызываются с Type-ID (компилятор вычисляет размер)
    5. Имеет версию явно для обработки массивов.
    6. Перераспределение (чтобы получить больше места) не обрабатывается интуитивно (из-за конструктора копирования).
    7. Будут ли они вызывать malloc / free, определяется реализацией.
    8. Может добавить новый распределитель памяти, чтобы справиться с нехваткой памяти (set_new_handler)
    9. оператор new / delete может быть переопределен юридически
    10. конструктор / деструктор, используемый для инициализации / уничтожения объекта

таНос / бесплатно

  • Выделяет / освобождает память
    1. Память, выделенная из «Кучи»
    2. Возвращает пустоту *
    3. Возвращает NULL при ошибке
    4. Необходимо указать требуемый размер в байтах.
    5. Выделение массива требует ручного расчета пространства.
    6. Перераспределение большего объема памяти просто (не нужно беспокоиться о конструкторе копирования)
    7. Они НЕ будут звонить новые / удалить
    8. Нет способа разделить пользовательский код на последовательность выделения, чтобы помочь с нехваткой памяти.
    9. malloc / free НЕ может быть переопределено юридически

Таблица сравнения функций:

 Feature                  | new/delete                     | malloc/free                   
--------------------------+--------------------------------+-------------------------------
 Memory allocated from    | 'Free Store'                   | 'Heap'                        
 Returns                  | Fully typed pointer            | void*                         
 On failure               | Throws (never returns NULL)    | Returns NULL                  
 Required size            | Calculated by compiler         | Must be specified in bytes    
 Handling arrays          | Has an explicit version        | Requires manual calculations  
 Reallocating             | Not handled intuitively        | Simple (no copy constructor)  
 Call of reverse          | Implementation defined         | No                            
 Low memory cases         | Can add a new memory allocator | Not handled by user code      
 Overridable              | Yes                            | No                            
 Use of (con-)/destructor | Yes                            | No                            

Технически память, выделенная new, поступает из Free Store, а память, выделенная malloc, из Heap. Являются ли эти две области одинаковыми - это детали реализации, что является еще одной причиной того, что malloc и new нельзя смешивать.


12
Может кто-то отредактировать, чтобы уточнить относительно "Free Store", а не кучи? Куча процесса - это хорошо известная независимая от языка (?) Концепция уровня операционной системы; откуда берется "Free Store"?
einpoklum

1
@einpoklum: это просто названия областей памяти. Ни то, ни другое не имеет ничего общего с концепцией языка, известной как «куча», или концепцией os «куча процессов». C ++ намеренно определен как нейтральный для платформы / ОС / компилятора. Поэтому использование определенной концепции ОС, такой как «куча процессов», подорвало бы гибкость стандарта.
Мартин Йорк,

4
@winterlight: Раньше это было правдой, но больше нет. Смотрите: linux.die.net/man/3/free If ptr is NULL, no operation is performed.
Мартин Йорк,

2
@LokiAstari Похоже, что «куча», «свободное хранилище» и «динамическая память / хранилище» являются синонимами: в « Путешествии по С ++» Бьярно Страуструпа он говорит: « newОператор выделяет память из свободного хранилища (также известное как динамическая память»). и куча. ) Стандарт C ++ 14, раздел 3.7.4 « Динамическое хранилище» гласит: «Объекты могут создаваться динамически во время выполнения программы (1.9) с использованием выражений new (5.3.4) и уничтожаться с помощью выражений удаления.»
Макс Heiber

2
@mheiber: значит, они могут быть одинаковыми. И несколько реализаций реализуют новое, вызывая malloc (обратите внимание, что обратное явно не разрешено). Но в нескольких реализациях эти области памяти полностью отделены друг от друга. Причина, по которой они были разделены, заключается в том, что это позволяет оптимизировать код управления памятью C ++ иначе, чем управление памятью C. Дело в том, что они могут быть одинаковыми, но вы не можете предположить, что они есть.
Мартин Йорк,

81

Наиболее существенным отличием является то, что newоператор выделяет память, затем вызывает конструктор и deleteвызывает деструктор, а затем освобождает память.


22
Строго говоря, новый оператор просто выделяет память. Это новое выражение, которое вызывает новый оператор, а затем запускает конструктор в выделенной памяти.
Дон Уэйкфилд,

Другое отличие заключается в том, где выделена память. Недавно я где-то видел, что malloc / free работает в куче, а new / delete работает в другой области памяти, имя которой теперь ускользает от меня. (Достаточно сказать, однако, что другую область, вероятно, можно рассматривать как другую кучу.)
RobH

2
@mgb: Да, вы правы в том, что объекты размещаются либо в «куче приложений», либо в стеке. Но @RobH относится к тому, что стандарт называет различными частями «Кучи приложений». Существует «куча», из которой malloc выделяет память, и «Free Store», из которой new выделяет память. Хотя в некоторых реализациях эти области перекрываются (это деталь реализации).
Мартин Йорк

1
Ваше утверждение на 100% верно, но просто не отвечает на заданный вопрос, см. Ответ ниже, есть причина, по которой оно набирает больше голосов, чем ваше.
Мурали

1
Все, что я пытался сказать, - это хотя бы упоминание о malloc / free, чтобы его можно было сравнить с отсутствующим в вашем ответе сравнением. Тем не менее, это уместное и точное заявление, поэтому я надеюсь, что вы поняли мою точку зрения. Во всяком случае, если бы только ТАК позволил мне вернуть мое отрицательное мнение, я бы от всего сердца сделал бы это.
Мурали

30

newвызывает ctor объекта, deleteвызывает dtor.

malloc& freeпросто выделить и освободить сырую память.


Что вы подразумеваете под сырой памятью?
Разрушитель

3
Сырая память ничего не сделала с этим. В нем еще не было построено ни одного объекта, в него ничего не было скопировано, и в большинстве случаев предыдущее содержимое не было перезаписано.
Джеймс Керран

14

new/ deleteэто C ++, malloc/ freeпроисходит от старого доброго C.

В C ++ newвызывает конструктор объектов и deleteвызывает деструктор.

mallocи free, начиная с темных веков до ОО, только выделяет и освобождает память, не выполняя никакого кода объекта.


9
«Выход из темных веков до ОО» звучит так, как будто вы намекаете, что new / delete лучше, чем malloc / free, но в действительности ни лучше, ни хуже, они просто используются по-разному. Заметьте, что я не тот, кто вас отверг, я просто догадываюсь.
Грэм Перроу

13

В C ++ new/ deleteвызовите Constructor / Destructor соответственно.

malloc/ freeпросто выделить память из кучи. new/ deleteвыделить память также.


10

Единственное сходство состоит в том, что malloc/ newоба возвращают указатель, который обращается к некоторой памяти в куче, и они оба гарантируют, что, как только такой блок памяти будет возвращен, он не будет возвращен снова, если вы сначала не освободите / удалите его. То есть они оба «выделяют» память.

Тем не менее, new/ deleteвыполнять произвольную другую работу, кроме того, через конструкторы, деструкторы и перегрузку операторов. malloc/ freeтолько когда-нибудь выделяю и освобождаю память.

Фактически, newон достаточно настраиваем, чтобы не обязательно возвращать память из кучи или даже выделять память вообще. Однако по умолчанию new.


7

Основное различие между new и malloc заключается в том, что new вызывает конструктор объекта, а соответствующий вызов delete вызывает деструктор объекта.

Есть и другие отличия:

  • newбезопасен mallocот типа , возвращает объекты типаvoid*

  • newвыдает исключение при ошибке, mallocвозвращает NULLи устанавливает errno

  • newявляется оператором и может быть перегружен, mallocявляется функцией и не может быть перегружен

  • new[], который распределяет массивы, является более интуитивным и безопасным для типов, чем malloc

  • malloc-извлеченные выделения могут быть изменены с помощью realloc, new-извлеченные распределения не могут быть изменены

  • mallocможет выделять N-байтовый кусок памяти, newнужно попросить выделить массив, скажем, charтипов

Смотря на различия, резюме - это malloc на C-esque, а новое на C ++ - esque. Используйте тот, который кажется правильным для вашей базы кода.

Хотя законно, что new и malloc реализуются с использованием разных алгоритмов выделения памяти, в большинстве систем new внутренне реализуется с использованием malloc, не приводя к разнице на уровне системы.


5

Есть несколько вещей, которые newэтого mallocне делают:

  1. new создает объект, вызывая конструктор этого объекта
  2. new не требует типизации выделенной памяти.
  3. Для этого не нужно выделять объем памяти, скорее, для этого нужно несколько объектов.

Так что, если вы используете malloc, то вам нужно явно делать вышеперечисленные вещи, что не всегда практично. Кроме того, newможет быть перегружен, но mallocне может быть.

Одним словом, если вы используете C ++, старайтесь использовать newкак можно больше.


4

также,

глобальные new и delete могут быть переопределены, malloc / free - нет.

в дальнейшем более новые и удаляемые могут быть переопределены для каждого типа.


3

newи deleteявляются примитивами C ++, которые объявляют новый экземпляр класса или удаляют его (таким образом вызывая деструктор класса для экземпляра).

mallocи freeявляются функциями C, и они выделяют и освобождают блоки памяти (по размеру).

Оба используют кучу, чтобы сделать распределение. mallocи freeтем не менее являются более «низкоуровневыми», поскольку они просто резервируют кусок памяти, который, вероятно, будет связан с указателем. Вокруг этой памяти не создаются никакие структуры (если только вы не считаете массив C структурой).


1
new в C ++ не объявляет экземпляр класса. Он (обычно) выделяет один из кучи и ничего не объявляет. Вы можете объявить экземпляр, просто объявив его, в этом случае он будет находиться в стеке или глобально, в зависимости от продолжительности хранения объявления.
Стив Джессоп

Ну, он выделяет пространство памяти для класса, но вы не можете «объявить» класс в стеке, не в реальном смысле хранения класса в стеке. Объявление включает в себя только указатель на класс, который всегда выделяется в стеке, а фактическая память, содержащая класс, находится в куче.
Хорхе Кордова

Да, ты можешь. В соответствии с тегами вопроса это C ++, поэтому объекты могут помещаться в стек. И новое не декларация, это выражение. Объявить что-то и выделить это - отдельные вещи.
Стив Джессоп

2

new и delete являются операторами в c ++; которые тоже могут быть перегружены. malloc и free являются функциями в c;

malloc возвращает ноль ptr, когда происходит сбой, а new создает исключение.

Адрес, возвращаемый функцией malloc, должен быть снова приведен к типу, так как он возвращает (void *) malloc (size). Новый возвращает типизированный указатель.


2
  • new - это оператор, тогда как malloc () - это функция.
  • new возвращает точный тип данных, тогда как malloc () возвращает void * (указатель типа void).
  • malloc (), память не инициализируется и значение по умолчанию является мусором, тогда как в случае нового память инициализируется со значением по умолчанию, например, с 'zero (0)' в случае с int.
  • delete и free () оба могут использоваться для указателей NULL.

0
  • Чтобы использовать malloc(), нам нужно включить <stdlib.h> или <alloc.h>в программу, которая не требуется для new.
  • newи deleteможет быть перегружен, но mallocне может.
  • Используя размещение new, мы можем передать адрес, где мы хотим выделить память, но это невозможно в случае malloc.

1
alloc.hне является стандартным заголовком. <new>Требуется использовать размещение нового.
MM

0

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

#include<iostream>


using namespace std;

class ABC{
public: ABC(){
    cout<<"Hello"<<endl;
  }

  void disp(){
    cout<<"Hi\n";
  }

};

int main(){

ABC* b=(ABC*)malloc(sizeof(ABC));
int* q = new int[20];
ABC *a=new ABC();
b->disp();

cout<<b<<endl;
free(b);
delete b;
//a=NULL;
b->disp();
ABC();
cout<<b;
return 0;
}

вывод :

Hello
Hi
0x2abfef37cc20

-3

1. новый синтаксис проще, чем malloc ()

2.new/delete - оператор, в котором malloc () / free () - это функция.

3.new/delete выполняется быстрее, чем malloc () / free (), потому что новый ассемблерный код напрямую вставляется компилятором.

4. мы можем изменить / удалить новое значение в программе с помощью оператора overlading.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.