2012-10-13 13 views
15

Ich garantiere, dass diese Frage zuvor gestellt wurde, aber ich konnte es nicht über die Suche finden; Entschuldigung im Voraus für irgendwelche Entlassungen.C Array Instanziierung - Stack- oder Heap-Zuordnung?

Es ist mein (möglicherweise falsches) Verständnis, dass Sie nur dem Stapel zuweisen, wenn Sie die Größe eines Objekts zur Kompilierzeit kennen. So im Fall eines Arrays initialisiert, können Sie eine davon tun (und das auf den Stapel gehen sollte):

char charArray[50]; 

Da die Größe dieses Arrays zum Zeitpunkt der Kompilierung bekannt ist, dies keine Probleme haben sollte.

Auf der anderen Seite, diese (glaube ich) ist auch gültige Code:

char anotherCharArray[someVariable + 50]; 

dies auch auf dem Stapel gehen würde? Ich bin ziemlich sicher, dass der Code segfolds, wenn Sie() dies freigeben, so dass es mich denken lässt, aber es macht keinen Sinn für mich. Ähnlich ist die 100% einzige Situation, in der Sie free() verwenden müssen, wenn die Daten über malloc zugewiesen wurden?

Vielen Dank im Voraus für Ihre Hilfe.

+2

@Shookit: Sie müssen angeben, ob Sie über lokale Variablen oder globale Variablen sprechen. –

+0

@PaulR Wenn das Array eine variable Länge hat, kann es nicht im globalen Gültigkeitsbereich sein. –

+1

Sie müssen zwischen dem * automatischen Speicher * und dem * Stack * unterscheiden, bei dem es sich um eine Low-Level-Methode zum Speichern von Daten handelt. Daten, die im automatischen Speicher abgelegt werden, können auch an anderen Stellen wie in Registern abgelegt werden. Im Fall eines lokalen Arrays mit unbekannter Größe (bekannt als VLA: s) kann der Compiler es auf den Stack legen, es ist auch erlaubt, den Speicher auf dem Heap zuzuweisen (solange es ihn an geeigneten Stellen freigibt). In der Tat, VLA: s passen nicht gut zusammen mit 'setjmp' /' longjmp', da sie undicht werden können (und dürfen dies vom C-Standard tun). – Lindydancer

Antwort

4

Ähnlich ist die 100% einzige Situation, in der Sie free() verwenden müssen, wenn die Daten über malloc zugewiesen wurden?

Ja. (Abgesehen von calloc und realloc sollte ihr Rückgabewert auch free() 'd sein. In ähnlicher Weise gibt es Funktionen, die malloc() verwenden, und diese Tatsache ist dokumentiert, zum Beispiel strdup() - der Rückgabewert dieser Funktionen soll ebenfalls mit freigegeben werden free(), natürlich.)

char anotherCharArray[someVariable + 50]; 

Würde dies auch auf den Stapel gehen?

Ja, es tut (in den meisten Implementierungen - natürlich, es ist nicht immer wahr, dass Sie davon ausgehen, aber auf den meisten Plattformen, es ist). Und ja, das ist ein gültiger Code, aber er ist nur Standard in C99.

+0

Alles in Ordnung, so scheint es, als ob mein größtes Missverständnis davon ausging, dass die Stapelspeicherzuweisung die Kenntnis der Größe zur Kompilierungszeit erfordert? Ich markierte dies als beantwortet (aber immer noch frei, meinen Kommentar zu beantworten :) – Shookit

+6

@ Shookit Ja, das ist ein völliges Missverständnis; eine bekannte Größe zu haben, ist irrelevant für die Zuordnung von etwas. Die einzige Verbindung besteht darin, dass in früheren Versionen von C aus verschiedenen historischen Gründen "automatische" Variablen eine bekannte Größe haben mussten und nur "automatische" Variablen auf dem Stapel zugewiesen werden können. –

+0

@JimBalter beantwortete Ihre Frage sehr gut :) –

7

Wenn char charArray[50]; im Dateibereich (außerhalb aller Funktionen) definiert ist oder static ist, wird es nicht auf dem Stapel liegen, es wird eine globale Vorbelegung bei der Startvariable des Programms sein. Wenn es nicht static ist und im Funktionsumfang definiert ist, wird es auf dem Stapel liegen.

char anotherCharArray[someVariable + 50]; kann nur im Funktionsumfang definiert werden und befindet sich auf dem Stapel.

Alle oben genannten gelten für typische Implementierungen von C. Atypische können den Heap anstelle des Stapels und anstelle des vorbelegten Speicherplatzes im Datenbereich des Programms verwenden.

Sie nicht free() was nicht zugeordnet wurde mit malloc(), calloc() oder . Einfach. Einige Funktionen können die Verwendung eines der obigen, z.B. POSIX strdup().

+1

Wenn wir im globalen Bereich sind, 'char someArray [variableLength]; 'ist nicht erlaubt ... –

+0

@ H2CO3 Hat die letzte Änderung Mehrdeutigkeit beseitigt? Ich sehe nicht, wo ich implizieren würde, dass dies im globalen Rahmen erlaubt ist. –