Unterschied zwischen Array-Typ und Array, die mit malloc zugewiesen wurden
Heute half ich einen Freund von mir mit einigen C-code, und ich habe festgestellt, dass einige seltsame Verhalten, dass ich nicht ihm erklären, warum es passiert war. Wir hatten die TSV-Datei mit einer Liste von Ganzzahlen, die mit einem int-jede Zeile. Die erste Linie wurde die Anzahl der Zeilen der Liste hatte.
Hatten wir auch eine c-Datei mit einem sehr einfachen "readfile". Die erste Zeile war zu Lesen, n die Anzahl der Zeilen, dann gab es ein Initialisierung:
int list[n]
und schließlich eine for-Schleife, der n mit einem fscanf.
Für kleine n (bis ~100.000), war alles in Ordnung. Allerdings haben wir festgestellt, dass, wenn n groß (10^6), ein segfault auftreten würde.
Schließlich wechselten wir die Liste der Initialisierung zu
int *list = malloc(n*sizeof(int))
alles und wenn Sie gut, auch bei sehr großen n.
Kann jemand erklären, warum dies geschah? was führte dazu, dass der segfault mit int Liste[n], das war gestoppt, wenn wir mit der Liste = malloc(n*sizeof(int))?
InformationsquelleAutor der Frage Jorge Leitão | 2012-05-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es mehrere verschiedene Stücke zu spielen.
Die erste ist der Unterschied zwischen der Deklaration einer array-als
und
In der ersten version, Sie deklarieren ein Objekt mit automatischer Speicherung Dauer. Dies bedeutet, dass die Matrix lebt nur so lange, wie die Funktion, dass Anrufe vorhanden. In der zweiten version, sind Sie immer Speicher mit dynamic storage duration, das heißt, es wird bestehen, bis es explizit aufgehoben mit
free
.Den Grund, dass die zweite version die hier arbeitet, ist eine Implementierung detail, wie C ist in der Regel zusammengestellt. Regel C-Speicher ist aufgeteilt in mehrere Regionen, einschließlich der stack (für Funktionsaufrufe und lokale Variablen) und den heap (für
malloc
ed-Objekte). Der stack in der Regel hat eine viel kleinere Größe als die Haufen; in der Regel so um die 8 MB. Als Ergebnis, wenn Sie versuchen, weisen Sie eine große Auswahl mitDann sind Sie vielleicht überschreiten der stack-Speicherplatz, wodurch der segfault. Auf der anderen Seite, wird der heap in der Regel hat eine enorme Größe (sagen wir, wie viel Platz Sie kostenfrei auf dem system), und so
malloc
ing ein großes Objekt wird nicht dazu führen, eine out-of-memory-Fehler.Im Allgemeinen, seien Sie vorsichtig mit variabler Länge arrays in C. Sie können leicht übersteigen stack-Größe. Lieber
malloc
es sei denn, Sie wissen, die Größe klein ist oder dass Sie wirklich nur wollen, dass das array für eine kurze Zeit.Hoffe, das hilft!
InformationsquelleAutor der Antwort templatetypedef
Reserviert Speicherplatz für
n
Ganzzahlen auf die Stapel, die in der Regel ziemlich klein. Mit Speicher auf dem stack ist viel schneller als die alternative, aber Sie ist ziemlich klein und es ist einfach zu overflow den stack (d.h. der Zuweisung von zu viel Speicher) wenn Sie Dinge tun, wie reservieren riesige arrays oder tun Rekursion zu tief. Sie müssen nicht manuell Speicher freigeben auf diese Weise zugeordnet, es erfolgt durch den compiler, wenn das array geht out of scope.malloc
auf der anderen Seite teilt Raum in der heap, die in der Regel sehr große im Vergleich zu den stack. Sie haben zu reservieren, eine viel größere Menge an Speicher auf dem heap zu erschöpfen, aber es ist viel langsamer, um Speicher auf dem heap, als es auf den Stapel, und Sie müssen es manuell freigeben überfree
wenn Sie fertig sind es zu benutzen.InformationsquelleAutor der Antwort Seth Carnegie
int Liste[n] speichert die Daten im stack, während malloc legt es in den heap.
Den Stapel ist beschränkt, und es ist nicht viel Platz, während der Haufen ist viel, viel größer.
InformationsquelleAutor der Antwort Asier Gutierrez
int list[n]
ist ein VLA, die reserviert auf dem stack statt am heap. Sie nicht haben, um frei (er befreit sich automatisch am Ende der function call) und es ordnet schnell, aber der Speicherplatz ist sehr begrenzt, da Sie herausgefunden haben. Sie verteilen müssen, größere Werte auf dem heap.InformationsquelleAutor der Antwort Puppy
Diese Erklärung reserviert Speicher auf dem stack
malloc reserviert auf dem heap.
Stack-Größe ist normalerweise kleiner als der heap, so dass, wenn Sie reservieren, zu viel Speicher auf dem stack erhalten Sie einen stackoverflow.
Siehe auch diese Antwort für weitere Informationen
InformationsquelleAutor der Antwort thumbmunkeys
Vorausgesetzt, Sie haben eine typische Implementierung in der Implementierung ist es sehr wahrscheinlich, dass:
Liste zugewiesen, die auf Ihrem Stapel, wo, wie:
reserviert Speicher auf dem heap.
Im Falle eines stack in der Regel gibt es ein limit, wie groß diese wachsen können (wenn Sie wachsen). Im Fall von einem Haufen gibt es immer noch eine Grenze, aber das ist eher viel zu groß (breit) beschränkt durch Ihr RAM+swap+Adressraum ist typischerweise mindestens eine Größenordnung größer sein, wenn nicht mehr.
InformationsquelleAutor der Antwort Flexo
Beim zuordnen mit einem
malloc
, Arbeitsspeicher ist von heap und nicht vom stack, und das ist viel mehr in der Größe begrenzt.InformationsquelleAutor der Antwort Tibor
Wenn Sie auf linux, können Sie ulimit -s auf einen größeren Wert und dies könnte für die stack-Allokation auch.
Wenn Sie Speicher auf dem stack, der Speicher bleibt bis zum Ende Ihrer Funktion Ausführung. Wenn Sie Speicher auf dem heap(mit malloc), können Sie den Speicher frei jede Zeit wollen Sie(noch vor dem Ende Ihrer Funktion Ausführung).
In der Regel, heap sollte verwendet werden, für die großen Speicherzuordnungen.
InformationsquelleAutor der Antwort Manik Sidana
Es ist ein Beispiel von statisch reservierten Arrays und zur compile-Zeit die Größe des Arrays bekannt sein wird. Und das array wird auf dem Stapel reserviert.
Es ist ein Beispiel eines dynamisch reservierten Arrays und die array-Größe bekannt sein wird, um Benutzer an der Laufzeit. Und das array wird reserviert auf dem heap.
InformationsquelleAutor der Antwort cammando