Яка різниця між новим / видаленням та malloc / free?


Відповіді:


466

новий / видалити

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

malloc / вільний

  • Виділяє / звільняє пам'ять
    1. Пам'ять, виділена з "Heap"
    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                            

Технічно пам’ять, виділена новим, надходить із "Безкоштовного магазину", тоді як пам'ять, виділена malloc, надходить із "Купи". Чи однакові ці дві області - це деталь реалізації, що є ще однією причиною того, що malloc та new не можна змішувати.


12
Чи може хтось редагувати детальніше про "Безкоштовний магазин" на відміну від купи? Купка процесів - це відома концепція на рівні операційної системи, незалежної від мови (?); звідки береться "Безкоштовний магазин"?
einpoklum

1
@einpoklum: Це лише назви областей пам’яті. Не має нічого спільного з мовною концепцією, відомою як "купа", або з концепцією os "процесами купи". C ++ свідомо визначається як платформа / ОС / компілятор, нейтральна. Таким чином, використання конкретної концепції ОС, на зразок "купи процесів", може підірвати гнучкість стандарту.
Мартін Йорк

4
@winterlight: Це було правдою, але вже не. Дивіться: linux.die.net/man/3/free If ptr is NULL, no operation is performed.
Мартін Йорк

2
@LokiAstari Це схоже на "купу", "безкоштовний магазин" та "динамічну пам'ять / сховище" - це синоніми: У Bjarne Stroustrup A Tour of C ++ він говорить: " newОператор виділяє пам'ять з безкоштовного магазину (також відомий як динамічна пам'ять і купа .) C ++ 14 Стандарту, розділ 3.7.4 на Dynamic Storage говорить «Об'єкти можуть створюватися динамічно під час виконання програми (1.9), використовуючи нові вирази (5.3.4), і знищуються з використанням ВИДАЛИТИ-вирази.»
Макс Хайбер

2
@mheiber: Це означає, що вони можуть бути однаковими. І кілька реалізацій реалізують нове за допомогою виклику malloc (зверніть увагу, навпаки явно заборонено). Але кілька реалізацій зберігають ці області пам'яті повністю відокремленими. Причина, за якою вони були окремими, полягає в тому, що це дозволяє оптимізувати код управління пам'яттю C ++ іншим способом, ніж управління пам'яттю C. Справа в тому, що вони можуть бути однаковими, але ви не можете припустити, що вони є.
Мартін Йорк

81

Найбільш релевантна відмінність полягає в тому, що newоператор виділяє пам'ять, потім викликає конструктор, і deleteвикликає деструктор, а потім передає пам'ять.


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

Ще одна відмінність полягає в тому, де виділяється пам'ять. Нещодавно я десь бачив, що malloc / free працює на купі, тоді як new / delete працює в іншій області пам’яті, ім'я якої зараз ухиляється від мене. (Досить сказати, однак, що іншу область, можливо, можна розглядати як чергову купу.)
RobH

2
@mgb: Так, ви правильні, що об'єкти розподіляються або на "купі додатків", або на стеці. Але @RobH посилається на те, що стандарт називає різні частини "Купи додатків". Існує "Купа", де malloc виділяє пам'ять і "Free Store", звідки новий розподіляє пам'ять. Хоча в деяких реалізаціях ці області перекриваються (це детальна інформація про реалізацію).
Мартін Йорк

1
Ви заявляєте, що на 100% вірно, але просто не відповідає на поставлене запитання. Дивіться відповідь нижче, є причина, чому він більше голосує, ніж ваш.
Муралі

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

30

newназиває ctor об'єкта, deleteвикликає dtor.

malloc& freeпросто виділити і звільнити необроблену пам'ять.


Що ви маєте на увазі під сирою пам’яттю?
Деструктор

3
Сирої пам’яті до цього нічого не було. Жоден об’єкт в ньому ще не побудований, нічого в нього не скопійовано, і в більшості випадків попередній вміст не був перезаписаний.
Джеймс Курран

14

new/ deleteє С ++, malloc/ freeпоходить від старого доброго С.

У C ++ newвикликає конструктор об'єктів і deleteвикликає деструктор.

mallocі free, виходячи з темних століть перед ОО, лише виділяють і звільняють пам'ять, не виконуючи жодного коду об'єкта.


9
"Вихід із темних віків до ОО" звучить так, що ви натякаєте на те, що нові / видалення кращі, ніж malloc / free, коли насправді, ні краще, ні гірше, вони просто мають різні види використання. Зауважте, що я не той злочинець, який вас порушив, я просто здогадуюсь.
Graeme Perrow

13

У C ++ new/ deleteзателефонуйте відповідно до конструктора / деструктора.

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


10

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

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

Насправді newє достатньо настроюваним, що не обов'язково повертає пам'ять із купи або взагалі виділяє пам'ять. Однак за замовчуванням new.


7

Основна відмінність new і malloc полягає в тому, що новий викликає конструктор об'єкта і відповідний виклик для видалення викликає деструктор об'єкта.

Є й інші відмінності:

  • 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

також,

глобальне нове та видалення можна змінити, malloc / free не може.

далі більше нового та видалення можна змінити на тип.


3

newі deleteце примітиви C ++, які оголошують новий екземпляр класу або видаляють його (таким чином викликаючи деструктор класу для екземпляра).

mallocі freeє функціями С і вони виділяють і вільні блоки пам'яті (за розміром).

Обидва використовують купу для виділення. mallocі freeтим не менше, вони є "низьким рівнем", оскільки вони просто резервують шматок пам'яті, який, можливо, буде пов'язаний з покажчиком. Навколо цієї пам'яті не створюються структури (якщо ви не вважаєте, що масив C є структурою).


1
new у C ++ не оголошує примірник класу. Він (зазвичай) виділяє один із купи, і він нічого не оголошує. Ви можете оголосити екземпляр, просто оголосивши його, і в цьому випадку він буде знаходитися в стеці або в глобальних точках, залежно від тривалості зберігання декларації.
Стів Джессоп

Ну, він виділяє простір пам'яті для класу, але ви не можете "оголосити" клас у стеку, не в реальному сенсі зберігання класу в стеку. Декларація включає лише вказівник на клас, який завжди виділяється в стеці, а фактична пам'ять, що містить клас, знаходиться в купі.
Хорхе Кордоба

Так, ти можеш. Відповідно до тегів запитань це C ++, тому об’єкти можуть переходити на стек. І нове не декларація, це вираз. Декларувати щось і виділяти це окремі речі.
Стів Джессоп

2

new і delete - це оператори в c ++; який теж може бути перевантажений. malloc і free функціонують в c;

malloc повертає null ptr, коли не вдається, а викиди нових кидків.

адресу, повернуту malloc, потрібно вводити заново, оскільки вона повертає (void *) malloc (size) Нове повернення введеного покажчика.


2
  • new є оператором, тоді як malloc () - це fucntion.
  • новий повертає точний тип даних, тоді як malloc () повертає void * (покажчик типу void).
  • malloc (), пам'ять не ініціалізована, а значення за замовчуванням - сміття, тоді як у випадку нового, пам'ять ініціалізується зі значенням за замовчуванням, як, наприклад, "zero (0)" у випадку з int.
  • delete and free () обидва можуть використовуватися для покажчиків "NULL".

0
  • Щоб користуватися програмою malloc(), нам потрібно включити <stdlib.h> або <alloc.h>в програму, яка не потрібнаnew .
  • newі deleteможе бути перевантажений, але mallocне може.
  • Використовуючи розміщення new, ми можемо передати адресу, куди ми хочемо виділити пам'ять, але це неможливо у випадку malloc.

1
alloc.hне є стандартним заголовком. <new>потрібно використовувати нове розташування.
ММ

0

Цей код для використання ключового слова для видалення або вільної функції. Але при створенні об’єкта вказівника за допомогою 'malloc' або 'new' та оперативної пам'яті об'єкта за допомогою видалення навіть цей вказівник об'єкта може бути функцією виклику в класі. Після цього використовуйте безкоштовно замість видалення, тоді він також працює після вільного оператора, але при використанні обох тоді лише об’єкт вказівника не може викликати функціонування в класі .. код наступний:

#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.