2010-05-15 14 views

Odpowiedz

32

Nie ma new/delete wyrażenie w C

Najbliższym odpowiednikiem są malloc and free functions, jeśli zignorujesz konstruktory/destruktory i bezpieczeństwo typu.

#include <stdlib.h> 

int* p = malloc(sizeof(*p)); // int* p = new int; 
... 
free(p);      // delete p; 

int* a = malloc(12*sizeof(*a)); // int* a = new int[12]; 
... 
free(a);       // delete[] a; 
+2

* @ KennyTM: * Czy 'sizeof (* p)' faktycznie dereferencja 'p', czy jest w pełni równoznaczne z pisaniem' sizeof (int) '? Wydaje się, że w pierwszym przypadku wyrażenie to potencjalnie powodowałoby błąd segmentacji (ponieważ 'p' nie jest jeszcze przypisany w tym momencie). W tym ostatnim przypadku prawdopodobnie wolałabym nadal pisać 'sizeof (int)', ponieważ istnieje mniejsze prawdopodobieństwo niezrozumienia tego, co robi to oświadczenie. – stakx

+5

@stakx: Operator 'sizeof' jest oceniany w czasie kompilacji. Nie ma dereferencji. 'sizeof (* p)' jest preferowany do 'sizeof (int)', ponieważ jeśli zmienisz typ 'p' na' double', kompilator nie może ostrzec cię o niedopasowaniu rozmiaru. – kennytm

+8

@stakx Operator 'sizeof' jest mapowaniem z ** typu ** na' size_t'. Wartość ** jego argumentu nie jest wcale interesująca. Na przykład w 'sizeof (1 + 2)', nie ma absolutnie potrzeby obliczania wyniku '3'. Operator 'sizeof' po prostu widzi wyrażenie typu' int + int' i sugeruje, że wynikiem jest również 'int'. Następnie mapuje 'int' na 4 (lub 2 lub 8, w zależności od platformy). To samo dzieje się z 'sizeof (* p)'. System typów wie, że na poziomie typu wyłuskanie 'int *' daje 'int'. 'sizeof' w ogóle nie jest zainteresowany wartością * * p, tylko typ ma znaczenie. – fredoverflow

3

Nie bezpośrednio dokładną repliką, ale zgodne odpowiedniki to malloc i za darmo.

<data-type>* variable = (<data-type> *) malloc(memory-size); 
free(variable); 

Brak konstruktorzy/destruktory - C i tak ich nie ma :)

Aby uzyskać pamięci rozmiarze, można użyć sizeof operatora.

Jeśli chcesz pracować z wielowymiarowych tablic, trzeba będzie go używać wielokrotnie (jak nowa):

int** ptr_to_ptr = (int **) malloc(12 * sizeof(int *)); //assuming an array with length 12. 
ptr[0] = (int *) malloc(10 * sizeof(int)); //1st element is an array of 10 items 
ptr[1] = (int *) malloc(5 * sizeof(int)); //2nd element an array of 5 elements etc 
+4

W C nie musisz rzucać z pustki * na inne wskaźniki. Jest to po prostu int * p = malloc (sizeof (int) * cElements); –

+0

Chris: Jesteś pewien? Nie pracowałem z C od dłuższego czasu, ale IIRC, musiałem to zrobić, ponieważ typ zwrotu malloc jest nieważny *. –

+0

W c 'void *' automatycznie konwertuje do innych typów wskaźników. Oddanie zwrotu malloc może spowodować błędy, jeśli nie uwzględniłeś 'stdlib.h', ponieważ parametry będą przyjmowane jako' int'. –

2

Używać malloc/free funkcje.

6

Należy zauważyć, że konstruktorzy mogą zgłaszać wyjątki w C++. Równowartość player* p = new player(); byłoby coś takiego w C

struct player *p = malloc(sizeof *p); 
if (!p) handle_out_of_memory(); 
int err = construct_player(p); 
if (err) 
{ 
    free(p); 
    handle_constructor_error(); 
} 

odpowiednik delete p jest prostsza, ponieważ destruktory powinny nigdy „rzut”.

destruct(p); 
free(p); 
+0

Jak wyglądałby "construct_player'? –

5

Zastosowanie new i delete w C++ łączy dwa odpowiedzialność - przydzielanie/zwalniania pamięci dynamicznej i inicjalizacji/zwalniania obiektu.

Jak mówią wszystkie inne odpowiedzi, najpopularniejszym sposobem przydzielania i zwalniania pamięci dynamicznej jest wywoływanie malloc i free. Możesz także używać funkcji specyficznych dla systemu operacyjnego, aby uzyskać dużą porcję pamięci i przydzielać do niej swoje obiekty, ale jest to rzadsze - tylko jeśli masz dość specyficzne wymagania, których nie spełnia malloc.

W C, a API zapewnia parę funkcji, które spełniają inne funkcje o new i delete.

Na przykład, api plik wykorzystuje parę otwartych i zamkniętych funkcji:

// C++ 
fstream* fp = new fstream("c:\\test.txt", "r"); 
delete fp; 

// C 
FILE *fp=fopen("c:\\test.txt", "r"); 
fclose(fp); 

może się okazać, że fopen wykorzystuje malloc przydzielić pamięci dla FILE struktury lub może statycznie przydzielić tabelę maksymalna liczba wskaźników pliku przy rozpoczęciu procesu. Chodzi o to, że interfejs API nie wymaga od klienta używania i free.

Inne interfejsy API udostępniają funkcje, które po prostu wykonują inicjalizację i zwalnianie części zamówienia - równoważne z konstruktorem i destruktorem, dzięki czemu kod klienta może korzystać z pamięci automatycznej, statycznej lub dynamicznej.Jednym z przykładów jest API pthreads:

pthread_t thread; 

pthread_create(&thread, NULL, thread_function, (void*) param); 

To pozwala klientowi większą elastyczność, ale zwiększa sprzężenie między biblioteką a klientem - klient musi znać rozmiar typu pthread_t, podczas gdy biblioteka obsługuje zarówno Przydzielanie i inicjowanie klienta nie wymaga znajomości rozmiaru typu, więc implementacja może się zmieniać bez zmiany klienta. Ani nie wprowadza tak dużego sprzężenia między klientem a implementacją, jak robi to C++. (Często lepiej jest myśleć o C++ jako metaprogramowaniu szablonu z vtables niż z języka OO)

+0

Czy możesz wyjaśnić, jakie specyficzne wymagania malloc nie spełnia? – Pacerier

+0

@Pacerier 'malloc' przydziela pamięć. 'operator new' (zwykle) przydziela pamięć * i * inicjuje pamięć, aby zawierała wartości dostarczone przez konstruktor klasy określonej przez obiekt. (istnieje zmienna 'operator new' o nazwie 'placement new', która nie alokuje pamięci, więc możesz użyć malloc dla pierwszej części, a new dla drugiej jeśli chcesz) –