2009-12-28 15 views
5

Zazwyczaj programuję w języku C++, ale używam funkcji clibrary dla mojego znaku *. Niektóre strony podręcznika podobne do "getline", mówi, że wejście powinno być tablicą malloced.Czy istnieje różnica między tablicami malloced a nowymi tablicami

Czy można zamiast tego używać "nowego"?

Widzę, że moja mała próbka działa, ale czy może to w pewnym momencie spowodować dziwne niezdefiniowane zachowanie?

Wiem, że "nowy" powinien pasować do "usunięcia", a "malloc" z "wolnym".

Nie używam również std :: string. A to jest zamierzone.

Dzięki

+0

Nie, to nie jest OK. Ale jeśli używasz C++, czemu nie użyć std :: getline()? –

+2

Ilekroć widzisz coś takiego w dokumentacji, musisz głębiej się zagłębić i dowiedzieć się, czy zalecają "wycentrowany" wskaźnik, ponieważ używają terminologii C lub ponieważ funkcja ma wywoływać realloc() lub free(). Najwyżej ocenione odpowiedzi poniżej zakładają pierwsze, chociaż uważam, że funkcja, o której mówisz, ma do czynienia z tą ostatnią, jak zaznacza Martin. Nie jest w porządku parowanie malloc/free i new/delete niepoprawnie, więc najlepiej wykonać dodatkowe badania dotyczące konkretnych funkcji, do których dzwonisz, gdy pojawi się ten problem. –

Odpowiedz

13

Bufor przekazany do getline() MUSI być malloced.

Powodem jest, że getline() może wywołać realloc() na buforze, jeśli wymagane jest więcej miejsca.

Polecenie realloc() like free() powinno być używane tylko z pamięcią przydzieloną przez malloc().To dlatego, że malloc() i nowy przydzielić pamięci z różnych obszarów składowania:

Zob. What is the difference between new/delete and malloc/free?

Zasadniczo nowe zastosowania „The«magazynu Free»natomiast malloc używa«hałdy»Oba te obszary są częścią "Stos aplikacji" (chociaż standard nie wymaga tak naprawdę stosu aplikacji, ponieważ jest to szczegół implementacji), chociaż oba są na "stosie aplikacji", obszary te nie muszą się pokrywać, niezależnie od tego, czy robią to szczegóły implementacji.

strona man dla getline():

Wskazówki linię:

Alternatywnie, przed wywołaniem getline() * lineptr może zawierać wskaźnik malloc() - przydzielony bufor * n bajtów . Jeśli bufor nie jest wystarczająco duży, aby pomieścić linię, getline() zmienia jego rozmiar za pomocą realloc(), aktualizując * lineptr i * n, jeśli to konieczne.

+2

@Martin: wskazujesz na funkcję rozszerzenia GCC "getline". Nie sądzę, że jest zbyt wielkim poleceniem używania tej nieprzenośnej funkcji, szczególnie dla początkujących. –

+1

@ Eli: w tym pytaniu mowa jest o 'getline'. –

+0

@ Eli: Polecam przed wszelkimi funkcjami C, w których istnieje użyteczna alternatywa C++. Ale pytanie dotyczy właśnie funkcji C getline(). A kiedy dokumentacja wyraźnie wspomina o używaniu pamięci malloc (ed), zwykle jest to bardzo dobry powód. –

2

Tak, to OK, aby użyć wskaźnika przyznaną z new gdy spodziewane jest „malloced” jeden.

Nawiasem mówiąc, getline nie jest ISO C. W standardowej bibliotece C++ jest getline, ale ten oczekuje od std::string. Dla standardowego odczytu pliku C powinieneś użyć fgets. Następujące prace (uproszczony kod zakładając istnienie od infile i nie sprawdza fgets wartości zwracanej - które prawdopodobnie powinny w rzeczywistym kodzie):

// infile is some open FILE* object 
int mylen = 100; 
char* line = new char[mylen]; 
fgets(line, mylen, infile) 

jednak obowiązkowego Zastrzeżenie: Jest znacznie lepiej użyć std::string i getline jeśli używasz C++.

+1

Wiem, że oryginalny standard C pochodzi z ANSI, ale jest to organ krajowy, a ISO jest teraz odpowiedzialny za standard. Spróbuj użyć "ISO C", jeśli możesz. – paxdiablo

+1

@paxdiablo: poprawiono na "ISO C". używanie ANSI to tylko zwyczaj z przeszłości :-) –

+5

Nie zawsze dobrze jest używać nowej (ed) pamięci, gdzie oczekiwane jest malloc (ed). Jeśli po prostu używa pamięci jako pamięci surowej dobrze. Ale jeśli procedury zarządzania pamięcią są używane na wskaźnikach, nie można tego założyć. getline() może potencjalnie wywoływać realloc() na przekazanym wskaźniku. Jest to równoważne wywoływaniu free() na wskaźniku, tzn. Jest niezdefiniowanym zachowaniem. –

1

Jest całkiem dobrze mieć "nową" tablicę zamiast "tablicy malloc'ed do tego celu.

Różnice między nimi są (aby wymienić niektóre z nich):

  • new/delete wywołać konstruktora/destruktora powiązanego obiektu przeciwieństwie malloc/darmo. Te ostatnie nie mogą wykonywać czynności inicjalizujących/deinicjalizacyjnych.
  • nowe zwraca wskaźnik odpowiedniego typu, ale wskazówka co malloc zwraca musi być typecasted (C++)
  • new/delete nie posiada realloc alternatywę przeciwieństwie new/delete

Te sprawy nie idą do znaczna różnica w twoim programie; tak jak podano powyżej, idealnie nadaje się do "nowego"

Twój kod nie zawiedzie, chyba że nowe lub malloc nie powiedzie się, w takim przypadku 'nowy' zgłasza wyjątek, a malloc zwraca wskaźnik NULL.

EDYCJA: Aby to zrobić, tablica musi być być "malloc'ed. Chyba wtedy się myliłem! Dzięki Martin! :)

+0

@Srivatsan Iyer: Przeczytaj to, aby uzyskać więcej różnic: http://stackoverflow.com/questions/240212/what-is-the-difference-between-new-delete-and-malloc-free –

+0

Dzięki! Właściwie po prostu próbowałem umieścić * kilka * punktów; nie większość z nich! : P – SuperSaiyan

+6

__FAIL__: Niepoprawne jest, że linie MUSZĄ być wyciosane. Zobacz poniżej. –

Powiązane problemy