Jaka jest różnica między new / delete a malloc / free?

Odpowiedzi:

466

nowy / usuń

  • Przydziel / zwolnij pamięć
    1. Pamięć przydzielona z „Free Store”
    2. Zwraca w pełni wpisany wskaźnik.
    3. nowa (wersja standardowa) nigdy nie zwraca NULL (wyrzuci w przypadku awarii)
    4. Są wywoływane z Type-ID (kompilator oblicza rozmiar)
    5. Ma wersję specjalnie do obsługi tablic.
    6. Ponowne przydzielanie (aby uzyskać więcej miejsca) nie jest obsługiwane intuicyjnie (z powodu konstruktora kopiowania).
    7. To, czy nazywają się malloc / free, jest określone w implementacji.
    8. Można dodać nowy alokator pamięci, aby poradzić sobie z brakiem pamięci (set_new_handler)
    9. operator nowy / usuń można zastąpić zgodnie z prawem
    10. konstruktor / destruktor używany do inicjalizacji / zniszczenia obiektu

malloc / za darmo

  • Przydziela / zwalnia pamięć
    1. Pamięć przydzielona z „Sterty”
    2. Zwraca pustkę *
    3. Zwraca NULL w przypadku niepowodzenia
    4. Należy podać wymagany rozmiar w bajtach.
    5. Przydział tablicy wymaga ręcznego obliczenia przestrzeni.
    6. Ponowne przydzielanie większej części pamięci jest proste (nie trzeba się martwić konstruktorem kopii)
    7. NIE będą wywoływać nowych / usuwać
    8. Nie ma sposobu na podzielenie kodu użytkownika na sekwencję alokacji, aby pomóc z małą ilością pamięci.
    9. Malloc / free NIE może zostać zastąpione prawnie

Tabela porównania funkcji:

 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                            

Technicznie pamięć przydzielona przez new pochodzi z „Free Store”, a pamięć przydzielona przez malloc pochodzi z „Heap”. To, czy te dwa obszary są takie same, jest szczegółem implementacji, co jest kolejnym powodem, dla którego nie można mieszać malloc i new.

Martin York
źródło
12
Czy ktoś może edytować, aby rozwinąć kwestię „Free Store” w przeciwieństwie do kupy? Sterta procesu jest dobrze znaną koncepcją niezależną od języka (?) Na poziomie systemu operacyjnego; skąd pochodzi „Free Store”?
einpoklum
1
@einpoklum: To tylko nazwy obszarów pamięci. Żaden z nich nie ma nic wspólnego z pojęciem języka znanym jako „sterta” ani z koncepcją systemu operacyjnego „sterta procesów”. C ++ jest celowo zdefiniowany jako neutralny dla platformy / systemu operacyjnego / kompilatora. Zatem zastosowanie konkretnej koncepcji systemu operacyjnego, takiej jak „stos procesów”, podważyłoby elastyczność standardu.
Martin York
4
@winterlight: To było kiedyś prawdą, ale już nie. Zobacz: linux.die.net/man/3/free If ptr is NULL, no operation is performed.
Martin York,
2
@LokiAstari Wygląda na to, że „kupa”, „wolna pamięć” i „dynamiczna pamięć / pamięć” są synonimami: W „ Tour of C ++ ” Bjarne Stroustrup mówi: „ newOperator przydziela pamięć z bezpłatnej pamięci (znanej również jako pamięć dynamiczna i sterty .) C ++ 14 standard, sekcja 3.7.4 na Dynamic Storage mówi "Przedmioty mogą być tworzone dynamicznie w czasie wykonywania programu (1.9), używając nowego wyrażenia (5.3.4), i zniszczone przy użyciu delete-wyrażeń."
Max Heiber
2
@mheiber: Oznacza to, że mogą być takie same. Kilka implementacji implementuje nowe, wywołując malloc (zauważ, że odwrotność jest wyraźnie niedozwolona). Ale kilka implementacji całkowicie oddziela te obszary pamięci. Powodem, dla którego były oddzielone, jest to, że pozwala to zoptymalizować kod zarządzania pamięcią C ++ w inny sposób niż zarządzanie pamięcią C. Chodzi o to, że mogą być takie same, ale nie można zakładać, że są.
Martin York,
81

Najbardziej istotną różnicą jest to, że newoperator przydziela pamięć, a następnie wywołuje konstruktor, a deletenastępnie wywołuje destruktor, a następnie zwalnia pamięć.

Pułapka
źródło
22
Ściśle mówiąc, nowy operator po prostu przydziela pamięć. Jest to nowe wyrażenie, które wywołuje nowego operatora, a następnie uruchamia konstruktor w przydzielonej pamięci.
Don Wakefield
Kolejna różnica polega na tym, gdzie pamięć jest przydzielana. Niedawno widziałem gdzieś, że malloc / free działa na stercie, podczas gdy new / delete działają w innym obszarze pamięci, którego nazwa mi teraz wymyka. (Wystarczy jednak powiedzieć, że ten inny obszar prawdopodobnie można uznać za kolejną kupę.)
RobH
2
@mgb: Tak, masz rację, że obiekty są przydzielane albo na „stosie aplikacji”, albo na stosie. Ale @RobH odnosi się do tego, co standard nazywa różnymi częściami „sterty aplikacji”. Istnieje „Sterta”, z której malloc przydziela pamięć, oraz „Darmowy sklep”, z którego nowa przydziela pamięć. Chociaż w niektórych implementacjach obszary te się pokrywają (jest to szczegół implementacji).
Martin York,
1
Twoje oświadczenie jest w 100% poprawne, ale po prostu nie odpowiada na zadane pytanie, zobacz odpowiedź poniżej, istnieje powód, dla którego jest więcej głosów niż twoje.
Murali,
1
Chciałem tylko powiedzieć, że powinna być przynajmniej wzmianka o malloc / free, aby kwalifikować się jako porównanie, którego brakowało w twojej odpowiedzi. Niemniej jednak jest to trafne i dokładne stwierdzenie, więc mam nadzieję, że zrozumiecie mój punkt widzenia. W każdym razie, jeśli tylko SO pozwoliłoby mi cofnąć moje zdanie, z całego serca zrobiłbym to.
Murali
30

newwywołuje ctor obiektu, deletewywołuje dtor.

malloci freepo prostu przydziel i zwolnij surową pamięć.

James Curran
źródło
Co rozumiesz przez surową pamięć?
Destructor,
3
Surowa pamięć nic nie zrobiła. Żaden obiekt nie został jeszcze w nim skonstruowany, nic nie zostało w nim skopiowane, aw większości przypadków poprzednia zawartość nie została nadpisana.
James Curran
14

new/ deleteto C ++, malloc/ freepochodzi ze starego, dobrego C.

W C ++ newwywołuje konstruktor obiektów i deletewywołuje destruktor.

malloci free, pochodząc z epoki ciemności przed OO, przydzielaj i zwalniaj pamięć, nie wykonując żadnego kodu obiektu.

Treb
źródło
9
„Przychodzący z epoki ciemności przed OO” brzmi, jakbyś sugerował, że nowy / usuń jest lepszy niż malloc / bezpłatny, podczas gdy w rzeczywistości żaden nie jest ani lepszy, ani gorszy, mają tylko różne zastosowania. Zauważ, że nie jestem tym, który cię ocenił, po prostu zgaduję.
Graeme Perrow
13

W C ++ new/ deletewywołaj odpowiednio Constructor / Destructor.

malloc/ freepo prostu przydziel pamięć ze sterty. new/ deleteprzydziel także pamięć.

Szyfrowane
źródło
10

Jedyne podobieństwa polegają na tym, że malloc/ newoba zwracają wskaźnik, który adresuje pewną pamięć na stercie, i oba gwarantują, że po zwróceniu takiego bloku pamięci nie zostanie on zwrócony, chyba że najpierw go zwolnisz / usuniesz. Oznacza to, że obie „alokują” pamięć.

Jednak new/ deletewykonuj dowolne inne prace dodatkowo, poprzez konstruktory, destruktory i przeciążenie operatora. malloc/ freetylko zawsze przydzielaj i zwalniaj pamięć.

W rzeczywistości newjest dostatecznie konfigurowalny, że niekoniecznie zwraca pamięć ze sterty, ani nawet nie alokuje pamięci. Jednak domyślnie newtak.

Steve Jessop
źródło
7

Główną różnicą między new i malloc jest to, że new wywołuje konstruktor obiektu, a odpowiednie wywołanie delete wywołuje destruktor obiektu.

Istnieją inne różnice:

  • newjest bezpieczny dla typu, malloczwraca obiekty typuvoid*

  • newzgłasza wyjątek w przypadku błędu, malloczwraca NULLi ustawia errno

  • newjest operatorem i może być przeciążony, mallocjest funkcją i nie może być przeciążony

  • new[], który przydziela tablice, jest bardziej intuicyjny i bezpieczny dla typu niż malloc

  • malloc-rozdzielone przydziały można zmienić za pomocą realloc, new-rozdziałane przydziały nie mogą być zmienione

  • mallocmoże przydzielić N-bajtową część pamięci, newnależy poprosić o przydzielenie tablicy, powiedzmy, chartypów

Patrząc na różnice, podsumowanie jest takie, że malloc to C-esque, nowy to C ++ - esque. Użyj tego, który wydaje się odpowiedni dla twojej bazy kodu.

Chociaż nowe i Malloc są implementowane przy użyciu różnych algorytmów alokacji pamięci, w większości systemów nowe są implementowane wewnętrznie przy użyciu Malloc, nie powodując różnic na poziomie systemu.

Walter
źródło
5

Jest kilka rzeczy, które newtego mallocnie robią:

  1. new konstruuje obiekt, wywołując konstruktor tego obiektu
  2. new nie wymaga rzutowania przydzielonej pamięci.
  3. Nie wymaga alokacji ilości pamięci, a raczej wymaga zbudowania pewnej liczby obiektów.

Tak więc, jeśli używasz malloc, musisz wyraźnie robić powyższe rzeczy, co nie zawsze jest praktyczne. Dodatkowo newmoże być przeciążony, ale mallocnie może być.

Jednym słowem, jeśli używasz C ++, spróbuj użyć newjak najwięcej.

herohuyongtao
źródło
4

również,

globalny nowy i usuń można zastąpić, malloc / free nie.

więcej nowych i usuwanych można zastąpić według typu.

DanJ
źródło
3

new i deleteprymitywami C ++, które deklarują nową instancję klasy lub ją usuwają (wywołując w ten sposób destruktor klasy dla instancji).

malloc i freefunkcjami C. Przydzielają i zwalniają bloki pamięci (pod względem wielkości).

Oba używają sterty do dokonania przydziału. malloci freemimo to są bardziej „niskim poziomem”, ponieważ po prostu rezerwują fragment pamięci, który prawdopodobnie zostanie powiązany ze wskaźnikiem. Wokół tej pamięci nie są tworzone żadne struktury (chyba że uważasz, że tablica C jest strukturą).

Jorge Córdoba
źródło
1
new w C ++ nie deklaruje wystąpienia klasy. (Zwykle) przydziela jeden ze sterty i niczego nie deklaruje. Możesz zadeklarować instancję, po prostu ją deklarując, w którym to przypadku będzie ona na stosie lub globalnie, w zależności od czasu przechowywania deklaracji.
Steve Jessop
Cóż, przydziela przestrzeń pamięci dla klasy, ale nie można „zadeklarować” klasy na stosie, nie w sensie przechowywania klasy na stosie. Deklaracja dotyczy tylko wskaźnika do klasy, który jest zawsze przydzielany na stosie, a rzeczywista pamięć przechowująca klasę znajduje się na stercie.
Jorge Córdoba
Tak, możesz. Według tagów pytań jest to C ++, więc obiekty mogą wchodzić na stos. A nowa nie jest deklaracją, jest wyrażeniem. Zadeklarowanie czegoś i przydzielenie go to osobne rzeczy.
Steve Jessop
2

new i delete są operatorami w c ++; który również może być przeciążony. malloc i free są funkcjami c;

malloc zwraca null ptr, gdy zawiedzie, a nowy zgłasza wyjątek.

adres zwrócony przez malloc musi być ponownie rzutowany według typu, ponieważ zwraca (void *) malloc (rozmiar) Nowy zwraca wskaźnik wpisany.

VishalTiwari
źródło
2
  • new jest operatorem, podczas gdy malloc () jest funkcją.
  • nowy zwraca dokładny typ danych, a malloc () zwraca void * (wskaźnik typu void).
  • malloc (), pamięć nie jest inicjowana, a wartość domyślna to śmieci, natomiast w przypadku nowej pamięć jest inicjowana wartością domyślną, podobnie jak „zero (0)” w przypadku int.
  • zarówno delete, jak i free () mogą być użyte dla wskaźników „NULL”.
Anurag Singh
źródło
0
  • Aby skorzystać z malloc(), musimy dołączyć <stdlib.h> lub <alloc.h>do programu, który nie jest wymagany new.
  • newi deletemoże być przeciążony, ale mallocnie może.
  • Korzystając z miejsca docelowego new, możemy przekazać adres, pod który chcemy przydzielić pamięć, ale nie jest to możliwe w przypadku malloc.
Ron Davis
źródło
1
alloc.hnie jest standardowym nagłówkiem. <new>jest wymagane, aby użyć nowego miejsca docelowego.
MM
0

Ten kod do użycia słowa kluczowego delete lub funkcji bezpłatnej. Ale kiedy tworzysz obiekt wskaźnika za pomocą „malloc” lub „new” i zwalniasz pamięć obiektu za pomocą kasowania, nawet ten wskaźnik obiektu może być funkcją wywołującą w klasie. Po tym użyj free zamiast usuń, to działa również po instrukcji free, ale kiedy używasz obu, wówczas tylko obiekt wskaźnika nie może wywołać funkcji w klasie .. kod wygląda następująco:

#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;
}

wynik :

Hello
Hi
0x2abfef37cc20
chirag kadam
źródło
-3

1. nowa składnia jest prostsza niż malloc ()

2.new/delete to operator, w którym funkcja malloc () / free () jest funkcją.

3.new/delete wykonuje się szybciej niż malloc () / free (), ponieważ nowy kod asemblera jest wklejany bezpośrednio przez kompilator.

4. możemy zmienić nowe / usunąć znaczenie w programie za pomocą przeciążenia operatora.

Nitesh
źródło