2009-12-28 19 views
5

Ich bin normalerweise in C++ programmieren, aber einige clibrary Funktionen für meine char *. Einige der Hilfeseiten wie für 'getline', sagt, dass die Eingabe ein Malloced-Array sein sollte.gibt es einen Unterschied zwischen Malloced-Arrays und neue Arrays

Ist es in Ordnung, stattdessen 'neu' zu verwenden?

Ich kann für meine kleine Probe sehen, dass es funktioniert, aber könnte dies irgendwann zu einem seltsamen undefinierten Verhalten führen?

Ich weiß, dass ein "neues" mit einem "löschen" und ein "malloc" mit einem "frei" übereinstimmen sollte.

Ich verwende auch nicht std :: string. Und das ist beabsichtigt.

Dank

+0

Nein, es ist nicht OK. Aber wenn Sie C++ verwenden, warum nicht std :: getline() verwenden? –

+2

Immer wenn Sie in der Dokumentation etwas Ähnliches sehen, müssen Sie tiefer graben und herausfinden, ob sie einen 'malloced' Zeiger empfehlen, weil sie C Terminologie benutzen oder weil die Funktion realloc() oder free() aufrufen soll. Die Antworten mit den meisten Stimmen gehen von ersterem aus, obwohl ich glaube, dass die Funktion, auf die Sie sich beziehen, mit letzterem zu tun hat, wie Martin hervorhebt. Es ist nicht in Ordnung, malloc/free und new/delete falsch zu koppeln. Daher ist es am besten, zusätzliche Untersuchungen zu den spezifischen Funktionen durchzuführen, die Sie aufrufen, wenn dies geschieht. –

Antwort

13

Der Puffer übergeben an getline() MUSS werden malloced.

Der Grund ist, dass getline() realloc() im Puffer aufrufen kann, wenn mehr Speicherplatz benötigt wird.

realloc() like free() sollte nur mit Speicher verwendet werden, der von malloc() zugewiesen wurde.Dies liegt daran, malloc() und neuen Speicher aus unterschiedlichen Speicherbereichen zuordnen:

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

Grundsätzlich neue Nutzungen „Die‚Free Store The Heap ‚‘, während malloc verwendet‘Beide Bereiche sind Teil die "Application Heap" (obwohl der Standard keinen Anwendungs-Heap erfordert, da dies ein Implementierungsdetail ist). Obwohl sie beide auf dem "Application Heap" sind, müssen diese Bereiche nicht überlappen. Ob sie dies tun, ist ein Detail der Implementierung.

Die Manpage für getline():

Hinweis dieser Zeile:

Alternativ vor getline() aufrufen, * lineptr kann einen Zeiger auf eine malloc() enthalten - zugewiesenen Puffer * n Bytes groß . Wenn der Puffer nicht groß genug ist, um die Linie zu halten, ändert getline() die Größe mit realloc() und aktualisiert * lineptr und * n nach Bedarf.

+2

@Martin: Sie zeigen auf eine GCC-Erweiterungsfunktion "getline". Ich denke nicht, dass es zu großartig ist, diese nicht portable Funktion zu empfehlen, besonders für Anfänger –

+1

@Eli: Die Frage erwähnt ausdrücklich "getline". –

+0

@Eli: Ich würde gegen alle C-Funktionen empfehlen, wo es eine brauchbare C++ - Alternative gibt. Die Frage bezieht sich speziell auf die C getline() -Funktionalität. Und wenn die Dokumentation ausdrücklich den Gebrauch von malloc (ed) memory erwähnt, gibt es normalerweise einen guten Grund, dies zu tun. –

2

Ja, es ist OK, um einen Zeiger mit new zugewiesen zu verwenden, wenn ein „malloced“ one erwartet wird.

Übrigens, getline ist nicht ISO C. Es gibt eine getline in Standard-C++ - Bibliothek, aber das erwartet ein std::string. Für das Lesen von Standard-C-Dateien sollten Sie fgets verwenden. Die folgenden Werke (vereinfachte Code Existenz infile Annahme und prüfen nicht fgets Rückgabewert - was wahrscheinlich soll man in echtem Code):

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

jedoch ein obligatorischen Hinweis: es ist viel besser std::string und getline zu verwenden, wenn Du benutzt C++.

+1

Ich weiß, dass der ursprüngliche C-Standard aus ANSI kam, aber das ist eine nationale Stelle und ISO ist jetzt für den Standard verantwortlich. Bitte versuchen Sie "ISO C" zu verwenden, wenn Sie können. – paxdiablo

+1

@paxdiablo: fixiert auf "ISO C". ANSI zu verwenden ist nur eine Angewohnheit aus vergangenen Zeiten :-) –

+5

Es ist nicht immer in Ordnung, neuen (ed) Speicher zu verwenden, wo malloc (ed) erwartet wird. Wenn es nur den Speicher als rohen Speicher verwendet. Wenn jedoch Speicherverwaltungsroutinen für die Zeiger verwendet werden, können Sie diese Annahme nicht treffen. getline() kann möglicherweise realloc() für den übergebenen Zeiger aufrufen. Dies entspricht dem Aufruf von free() auf dem Zeiger, d.h. es ist ein undefiniertes Verhalten. –

1

Es ist vollkommen in Ordnung, ein 'neu'-Array statt' Malloc'-Array zu diesem Zweck zu haben.

Die Unterschiede zwischen den beiden sind (einige von ihnen zur Liste):

  • neu/löschen rufen Sie den Konstruktor/Destruktor des zugehörigen Objekts im Gegensatz zu malloc/free. Letzteres kann keine Initialisierungs-/Deinitialisierungs-Materialien ausführen.
  • neue gibt einen Zeiger der richtigen Art, aber der Zeiger, welche malloc kehrt typecasted werden muss (C++)
  • neu/löschen nicht im Gegensatz zu neuen realloc Alternative hat/

Diese Dinge löschen sind nicht zu gehen machen Sie viel Unterschied in Ihrem Programm; Wie oben erwähnt, ist es völlig in Ordnung, sich für "neu" zu entscheiden.

Ihr Code wird nicht fehlschlagen, es sei denn, new oder malloc schlägt fehl. In diesem Fall gibt 'new' eine Ausnahme aus, und malloc gibt einen NULL-Zeiger zurück.

EDIT: Für den Zweck, das Array muss ‚malloc'ed werden. Ich glaube, ich lag damals falsch! Danke Martin! :)

+0

@Srivatsan Iyer: Lesen Sie dies für weitere Unterschiede: http://StackOverflow.com/Questions/240212/what-is-the-difference-between-new-delete-and-malloc-free –

+0

Vielen Dank! Eigentlich habe ich nur versucht, * einige * Punkte einzubringen; nicht die meisten von ihnen! : P – SuperSaiyan

+6

__FAIL__: Das ist falsch, die Zeilen MÜSSEN malloced werden. Siehe unten. –

Verwandte Themen