Jaki jest odpowiednik nowego/usunięcia C++ w C?Jaki jest odpowiednik nowego/usunięcia C++ w C?
Czy to samo w C/C++?
Jaki jest odpowiednik nowego/usunięcia C++ w C?Jaki jest odpowiednik nowego/usunięcia C++ w C?
Czy to samo w C/C++?
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;
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
W C nie musisz rzucać z pustki * na inne wskaźniki. Jest to po prostu int * p = malloc (sizeof (int) * cElements); –
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 *. –
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'. –
Używać malloc/free funkcje.
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);
Jak wyglądałby "construct_player'? –
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)
Czy możesz wyjaśnić, jakie specyficzne wymagania malloc nie spełnia? – Pacerier
@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) –
* @ 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
@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
@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