Woher wissen Sie, wie viel Speicherplatz reservieren mit malloc()?
Ich bin ein totaler C Neuling, ich komme aus der C#. Ich habe gelernt über memory-management und die malloc()
Funktion. Ich habe auch kam in diesem code:
char *a_persons_name = malloc(sizeof(char) + 2);
Was ich nicht verstehe, ist, wie viel Speicherplatz dies ist die Zuteilung für a_persons_name
. Ist es die Zuweisung von 2 Zeichen (zB. AB) oder etwas anderes?
Ich weiß auch, dass manchmal kann man "Glück" mit malloc
und nutzen Speicherplatz (was dazu führen kann, dass Daten beschädigt und die seg faults). Also Woher weiß ich wie viel Platz ich reservieren und wie viel werde ich brauchen?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das snippet ist die Zuteilung der genug Platz für eine 2-Zeichen-Namen.
In der Regel der string-Puffer wird gefüllt von irgendwo, also I/O. Wenn die Größe des Strings ist nicht bekannt, vor der Zeit (z.B. beim Lesen von Datei oder Tastatur), einer von drei Ansätzen werden im Allgemeinen verwendet:
Definieren Sie eine maximale Größe für eine gegebene Zeichenfolge zuweisen, die Größe + 1 (für die null-terminator), Lesen am meisten, dass viele Zeichen, und Fehler oder blind zu kürzen, wenn zu viele Zeichen geliefert wurden. Nicht sehr user-freundlich.
Umverteilung in Stufen (vorzugsweise mit geometrischen Reihe, z.B. zu verdoppeln, zu vermeiden quadratischen Verhalten), und Lesen Sie weiter, bis das Ende erreicht wurde. Nicht gerade einfach zu Programmieren.
Reservieren Sie eine Feste Größe und hoffe, dass es nicht überschritten werden, und Absturz (oder gehört werden) schrecklich, wenn diese Annahme fehl. Einfach zu code, leicht zu brechen. Zum Beispiel, sehen Sie
gets
in der standard-C-Bibliothek. (Nie diese Funktion verwenden.)Gut, für den Anfang,
sizeof(char)
ist immer 1, so konnte man nurmalloc(3)
.Was du bist Zuteilung es ist genug Platz für drei Charaktere. Aber denken Sie daran, Sie brauchen eine für ein null-Abschlusszeichen für C-strings.
Dem, was Sie neigen dazu zu finden, sind Dinge wie:
genug Stauraum für ein name-und terminator-Charakter (wenn man bedenkt, dass die Zeichenfolge "xyzzy" wird im Speicher gespeichert, wie:
Manchmal mit nicht-char-basierten arrays, Sie werden sehen:
welche genügend Platz für 22 zahlen.
int *intArray = malloc(sizeof(*intArray) * 22);
malloc()
wird reserviert einen Speicherblock und gibt einen Zeiger auf diesen Speicher bei Erfolg, und NULL, wenn nicht erfolgreich. die Größe des Speicherblocks, der angegeben ist durchmalloc
's argument, in bytes.den
sizeof
operator gibt die Größe des Arguments in bytes.dies wird genügend Raum für einen 49-Zeichen-string (einen C-Stil-string muss beendet werden, indem eine NULL (
'\0'
) Zeichen), nicht einschließlich der NULL-Zeichen und PunktsomeString
an, dass der Speicher.Sieht es aus wie Sie den code in deine Frage sollte
malloc(sizeof(char) * 2);
alssizeof(char) + 2
macht keinen Sinn.beachten Sie, dass
sizeof(char)
ist garantiert immer gleich 1 (byte) -- aber die Erinnerung Repräsentation von anderen Typen (wie lange) kann variieren zwischen Compiler.Der Weise, dass Sie (un)glücklich mit dynamisch zugewiesenen Speicher ist, wenn Sie versuchen zu Lesen/schreiben außerhalb der Speicher, den Sie zugewiesen haben.
Beispielsweise
Die erste Zeile weist genug Platz für 9 Zeichen, und ein NULL-Zeichen.
Die zweite Zeile versucht zu kopieren 20 Zeichen (19 + NULL) in den Arbeitsspeicher. Dadurch kommt es zu einem Pufferüberlauf und möglicherweise bewirken, dass etwas unglaublich witzig, wie das überschreiben von benachbarten Speicher, oder verursacht einen segmentation Fault.
In der Dritten Zeile funktionieren könnte, zum Beispiel, wenn es zugeordnete Speicher rechts neben classextender und "Hallo, Welt!" lief in den Arbeitsspeicher, es könnte drucken Sie Ihre string plus, was war in den nächsten Speicherplatz. Wenn dieser zweite Raum war NULL beendet, es würde dann aufhören-es sei denn, er war es nicht, in dem Fall würde es Wandern aus und schließlich segfault.
Diesem Beispiel ist eine ziemlich einfache operation, aber es ist so leicht schief gehen. C ist heikel -- vorsichtig sein.
Ihren Anruf
malloc
zugewiesen werden 3 bytes an Speicher.sizeof(char)
ist 1 byte und 2 Byte angegeben sind, ausdrücklich zu. Dies gibt Ihnen genügend Platz für einen string der Größe 2 (zusammen mit dem terminierungszeichen)So weisen drei bytes, 1 für sizeof(char), plus zwei. Nur sehen, dass die Linie aus dem Zusammenhang, ich habe keine Möglichkeit zu wissen, warum Sie zugeordnet werden würde, die so oder so wenn es richtig ist (es sieht fischig zu mir).
Müssen Sie, um genügend Speicher zu halten, was Sie brauchen, um in Sie setzen. Zum Beispiel, wenn Sie beim reservieren von Speicher zu halten, eine Zeichenfolge, die Sie brauchen, um ausreichend Speicher zuzuweisen, um die längste Zeichenfolge erwartet, plus ein byte für die abschließende null. Wenn man sich mit ASCII-strings, das ist einfach: ein byte pro Zeichen plus eins. Wenn Sie mit unicode-strings, werden die Dinge komplizierter.
Ersten Punkt - es ist eine gute Angewohnheit, nie die absoluten zahlen im argument von malloc verwenden Sie immer die sizeof-und ein Vielfaches. Wie oben schon gesagt, der Speicher für einige Arten variiert mit compiler und Plattform. Um zu garantieren, gettin genug Platz für ein array vom Typ 'blob' ist es am besten, so etwas wie dieses:
Diese Weise, unabhängig von der Art ist, aber es sieht in den Speicher bekommen Sie genau die richtige Menge.
Zweitens segfaults etc.
C, wie ein low-level-Sprache, hat kein bounds checking. Dies bedeutet, dass es nichts zu überprüfen, die Sie suchen in einem index nicht im array. In der Tat ist es nicht stoppen Sie den Zugriff auf den Speicher auch noch irgendwo, wenn es gehört nicht zu Ihrem Programm (obwohl Ihr Betriebssystem möglicherweise, das ist, was ein segfault ist). Dies ist, warum, wenn Sie übergeben Sie ein array, um in C Sie brauchen, um passieren Ihre Länge, so dass die Funktion erhalten die array weiß, wie groß es ist. Vergessen Sie nicht, dass ein "array" ist eigentlich nur ein Zeiger auf das erste element.
Dies ist sehr hilfreich bei der übergabe von strings um - jedes string-argument werden würde, die zwei Argumente, so dass ein cheat benutzt wird. Alle standard-C-string ist NULL-terminiert. Das Letzte Zeichen in der Zeichenfolge sein sollte-ASCII-Wert 0. Alle string-Funktionen arbeiten, sowie das array, bis Sie sehen, dass und dann stoppen. Auf diese Weise Sie nicht überrennen das array, aber wenn Ihr es nicht aus irgendeinem Grund, werden Sie.
Das verstanden
ist 5, aber um es zu speichern müssen Sie ein oder mehrere Zeichen. E. g.:
Und ja, sizeof(char) ist überflüssig, weil es wird definiert als 1, aber ich finde es übersichtlicher und es ist definitiv eine gute Gewohnheit.
p_data = malloc(sizeof(blob) * length_of_array);
p_data = malloc(sizeof *p_data * length_of_array);
da hängt es nicht von der Codierung der Typ rechts ab und halten es direkt als code-änderungen. 2) Beispiel der Verwendung:str2 = malloc(sizeof *str2 * (strlen(str1) + 1));