trotz sizeof(char)*2 [malloc], unendlich Zeichen sichern! wieso?
-
Hi,
ich weiß nicht, aber irgentwie kommt mir das spannisch vor.
Als ich mal wieder ein Programm von mir debuggen musste ist mir was seltsames aufgefallen, ich weiß nicht warum das so ist, hier mal ein Beispiel wie es in etwa aussieht:#include <stdio.h> #include <string.h> int main() { char *string; string=(char*) malloc(sizeof(char)); strcpy( string, "Hallo Welt dynamisch www.c-plusplus.net sdxgcvfd\n" "dscviodsnckodsnckodsnckdnknkosdnckdvnskdnvkosdn\n" "sdiovnokdsnckodsnkdnvcsdnvsdknvskvsdnkghjghjghj\n" "sdvksdnkcvdsnknckdsncksdncsdncsdoncodsncdsoncdf\n" "sdokvcndskoncsodncdsncdsoncokdscnsdkdfgfdgfdfgf\n" ); printf("%s", string); return 0; }
Das ist die Ausgabe:
ciever2k@Hades:/windows/d/coden=-/projects/wesley/test # ./malloc1 Hallo Welt dynamisch www.c-plusplus.net sdxgcvfd dscviodsnckodsnckodsnckdnknkosdnckdvnskdnvkosdn sdiovnokdsnckodsnkdnvcsdnvsdknvskvsdnkghjghjghj sdvksdnkcvdsnknckdsncksdncsdncsdoncodsncdsoncdf sdokvcndskoncsodncdsncdsoncokdscnsdkdfgfdgfdfgf ciever2k@Hades:/windows/d/coden=-/projects/wesley/test #
Komischer weise konnte ich jetzt mehr als nur ein Zeichen kopieren, aber warum?
Es müsste doch einen Buffer Overflow/Segmentation Fault geben da der Return Wert auf dem Stack nicht mehr passt.mfg
-
nö, du zerschießt dir doch den Heap, nicht den Stack. Ausserdem gibts kein "müßte", das ist undefiniertes Verhalten, da darf alles passieren, muß aber nicht.
-
Nicht komischerweise konntest du mehr als ein Zeichen kopieren, das ist in C so möglich, es finden keine Bereichsprüfungen statt.
Du schreibst aber mit deinem falschen
string=(char*) malloc(sizeof(char));
gnadenlos über den von dier reservierten Bereich hinaus. Ob das zu einem Betriubsystemfehler führt oder nicht hängt vom OS und dem Zufall ab.
Deine Version hat genau 1 Platz für eine Zeichen reserviert.Ob du dir den Heap oder den Stack zerschießt kann ich im Moment nicht sagen, Hängt viel von der Optimierung des Kompilers ab. Bei großem Stackrahmen nehmen ein paar Compiler lokale Variablen inclusive Strings vom Stack, andere prinzipiell vom Heap
Die korrekte Allocierung wäre
string=(char*) malloc(sizeof(char)*Anzahl_der_Zeichen_plus_eins);
Die +1 in der Allocierung ist nötig um die \0 am Ende des Strings speichern zu können.
-
PAD schrieb:
Ob du dir den Heap oder den Stack zerschießt kann ich im Moment nicht sagen, Hängt viel von der Optimierung des Kompilers ab. Bei großem Stackrahmen nehmen ein paar Compiler lokale Variablen inclusive Strings vom Stack, andere prinzipiell vom Heap
Willst du damit jetzt sagen, dass manche Compiler bei malloc auf dem Stack allozieren?
-
Meine das bei CrossCompileren die für embedded Systeme arbeiten gesehen zu haben.
-
Krass, dabei haben Mikrocontroller meistens nicht gerade viel Stack ...
-
btw.
1. ist sizeof(char) immer 1 und deswegen überflüssig
2. sollte man den Rückgabewert von malloc nicht casten
-
kingruedi schrieb:
btw.
1. ist sizeof(char) immer 1 und deswegen überflüssigMeines Wissens wird sizeof() ja zur Compile-Zeit ausgewertet, also kommts nicht wirklich drauf an und man hat gleich noch dokumentiert, wie man auf das eine Byte kommt...
-junix
-
aber es ist mehr zu lesen.
du schreibst ja auch
i++;
statt
i = i + 1;
oder?
-
Du vergleichst mal wieder äpfel mit birnen. Während die von dir angeführten Beispiele alle die selbe Bedeutung haben (nämlich i auslesen und eins zum ausgelesenen wert hinzuzählen und wieder nach i schreiben), hat eine simple Ziffer '1' keine derartige Information hinterlegt. Es heisst schlicht, man will 1 Byte reservieren. während sizeof(char) ganz klar noch die Begründung, wieso man 1 byte reservieren will mitliefert...
Das nennt man selbstdokumentierend. Und schwupps hab ich mir 1 Zeile Kommentar gespart... (denn WIESO ich ausgerechnet nur 1 und nicht 100 Byte brauche, das muss ich ja sowieso irgendwo begründen?)Ausserdem schreibst du ja auch sizeof(myStruct) und nicht 123 wenn du eine 123 Byte grosse Struktur hast?
-junix
-
junix schrieb:
während sizeof(char) ganz klar noch die Begründung, wieso man 1 byte reservieren will mitliefert...
Verstehe ich nicht. Wenn da steht 'char *p = malloc(...)' dann ist davon auszugehen, dass p mal so etwas ähnliches wie ein String werden soll. Ein 'sizeof(char)' deutet an, dass der Schreiber der Überzeugung war, ein sizeof(char) müsste nicht überall 1 liefern (wobei er sich idR im restlichen Programm um Portabilität überhaupt nicht kümmert ...). Außerdem macht man sich einen riesigen Aufwand, wenn man diesen char mal auf einen anderen Typen umändern will -- und das für einen Aufwand, der überflüßig war und ist. 'sizeof(typ)' ist pfui. Man schreibt einfach immer 'sizeof *p', das schlägt zwei Fliegen mit einer Klappe. Es ist hochselbstdokumentierend und man kann bequem den Typ ändern.
-
weil 123 keine konstante groesse ist.
eine struct hat auf jedem compiler eine andere groesse.bei char ist das nicht so. denn 1 char ist 1 byte.
deswegen schreibe ich zB
char* p=malloc(strlen("Hallo Welt")+1); strcpy(p,"Hallo Welt"); free(p); //und nicht char* p=malloc( (strlen("Hallo Welt")+1) * sizeof char); strcpy(p,"Hallo Welt"); free(p);
allerdings ist es nicht so schlimm wenn man sizeof(char) schreibt - man wird nur einige leute damit verwundern, aber schaden tut es nicht.