newbie Fragen zu malloc und sizeof
Kann mir jemand erklären, warum mein Aufruf von malloc mit einem string-in Größe 6 gibt eine sizeof von 4 Byte? In der Tat, jedes integer-argument gebe ich malloc bekomme ich eine sizeof von 4. Nächsten, ich bin versucht zu kopieren von zwei strings. Warum ist meine Ausgabe der kopierten Zeichenfolge (NULL)?
Folgendes ist mein code:
int main()
{
char * str = "string";
char * copy = malloc(sizeof(str) + 1);
printf("bytes allocated for copy: %d\n", sizeof(copy));
while(*str != '\0'){
*copy = *str;
str++;
copy++;
}
copy = '\0';
printf("%s\n", copy);
}
- kopieren='\0' sein sollte *kopieren='\0'
Du musst angemeldet sein, um einen Kommentar abzugeben.
sizeof(str)
gibt die Größe eines Zeigers vom Typchar*
. Was Sie tun sollten, istmalloc
die Größe der Zeichenfolge selbst:Auch diese Zeilen:
Umgeschrieben werden kann leicht in C so:
strcpy(copy, str);
ist wahrscheinlich effizienter als das, was Sie haben.';'
null-Anweisung mit einer{}
oder, noch besser, einecontinue;
- Anweisung. Und ja, @Lutz,strcpy()
ist wahrscheinlich effizienter als auch leichter lesbar.*copy = '\0';
erforderlich ist, dies zu beheben, ansonsten gute Antwort.Zuerst sollten Sie verstehen, dass sizeof(xxx), wobei xxx Links Wert Ausdruck (eine variable) ist immer äquivalent zu tun sizeof(Art von xxx). Also was wirklich tun, Ihre sizeof(str) ist die Rücksendung der Größe eines char *, das ist die Größe von einem anderen Zeiger. Auf einem 32-bit-Architektur erhalten Sie 4, auf einer 64 bit Architektur werden es 8, etc.
So, wie andere auch, erklärt Sie müssen wissen, die Länge der Zeichenfolge, die Sie zuweisen möchten, und fügen Sie 1 zum speichern der terminal - \0, C implizit zu setzen, die am Ende des strings.
Aber zu tun, was Sie wollen (eine Zeichenfolge kopieren und zuweisen nötigen Platz, wird es einfacher und effizienter zu bedienen strdup, das tut genau das : ein malloc und ein strcopy.
Sollten Sie auch nicht vergessen Sie Speicherplatz frei, indem Sie selbst reserviert (mit malloc, calloc, strdup oder jede andere Zuordnung Funktion). In C wird es nicht gehen Weg, wenn die zugewiesene variable geht out of scope. Es wird bleiben, bis Sie das Ende des Programms. Das nennt man ein memory-leak.
Einen letzten Punkt : ich änderte Nachricht an bytes mindestens zugewiesenen, weil Sie nicht wirklich wissen, die zugeordnete Größe beim Aufruf von malloc. Sehr oft weist einen geringfügig größeren Raum, was Sie gefragt haben. Ein Grund dafür ist, dass in vielen Speicher-Manager freie Blöcke verknüpft sind, zusammen mit einigen versteckten Daten Struktur und jeden zugewiesenen block in der Lage sein sollten, um mindestens eine solche Struktur, eine andere ist, dass die zugewiesenen Blöcke sind immer so ausgerichtet werden, kompatibel mit jeder Art ausrichten.
Hoffe, es wird Ihnen helfen zu verstehen, C ein wenig besser.
strdup()
ist eine benutzerdefinierte Funktion, aber es ist so trivial einfach zu Rollen Sie Ihre eigenen, dass es nicht eine große Sache.Sich die Größe des str Zeiger (4 bytes), nicht das, was es zeigt, zu?
char
- Typ) ist 1, das ist noch weniger nützlich. Sie müssen die Länge der Zeichenfolge, wie in @AraK Antwort.sizeof(str)
liefert den notwendigen Raum zum speichern der Zeiger auf den string, nicht den string selbst. Sie können die Größe des Strings mitstrlen(str)
zum Beispiel.Dann wird Sie beeinflussen Ihre
copy
Zeiger auf eine Ganzzahl, die den Wert 0 hat (der Charakter'\0'
). Es ist das gleiche wiecopy = NULL
, das ist, was die Funktion printf() zeigt, Sie.Gegen die zweite Fragen, die durch die Ausführung der Anweisung
copy++
Sie Sie geändert haben, den Wert voncopy
(das heißt, die Adresse im Speicher, die hält einchar
array), so dass durch die Zeit, die Sie drucken Sie es aus, es ist deutete an das Ende des Arrays eher als der Anfang (der Wert, der zurückgegeben wird, durchmalloc()
). Sie benötigen eine extra variable zu aktualisieren Sie den string und Zugriff auf den Anfang der Zeichenkette:Bearbeiten zu reparieren
malloc/sizeof
Problem - Dank CL.malloc(sizeof(str) + 1)
-sizeof(str)
istsizeof(char *)
4 ist auf den meisten Plattformen und ist unabhängig von der Länge der Zeichenfolge.sizeof() liefert die Größe des aktuellen Typs der variable ist. Also, wenn Sie definieren Ihren Typ als char *, es gibt die Größe eines Zeigers.
Aber wenn du deine variable ein array, sizeof liefert dann die Größe des Arrays selbst, die alles tun würde, was Sie tun möchten:
assert(strlen(ptr) == 10);
für Symmetrie und Vollständigkeit.NULL
.copy = '\0'
; setzt den Zeiger und macht esNULL
.*copy = '\0'
weilcopy = '\0'
setzt den Zeiger auf'\0'
(das istNULL
alsint
- Typ).Können Sie verwenden:
size_t malloc_usable_size (void *ptr);
statt : sizeof
Aber es gibt die Reale Größe des allozierten Speicherblocks! Nicht die Größe, die Sie übergeben malloc!