String dynamisch vergrößern
-
Hallo
Ich arbeite an einer Funktion die mir zwei Strings verkettet und als neuen String zurückgibt. Das ganze habe ich als Konsolenprogramm getestet und hat wunderbar funktioniert, jetzt wollte ich die Funktion in einem Win32 Programm testen, das Programm stürzt aber immer beim aufruf der Funktion ab und verändert wohl etwas am speicher, ich kann danach das Programm nicht mehr kompilieren, sprich ich habe keinen zugriff mehr auf die *.exe (erst nach neustart).
Also hab ich die vermutung das ganze macht irgendetwas mit meinem speicher was es nicht tun sollte, interessanterweise funktioniert es aber anstandslos in der konsole. (ich benutze Pelles C IDE)
Zur Funktion, ich habe einen Zeiger auf einen besthenden char String, übergebe diesen der Funktion, übergebe den hinzuzufügenden String und erhalte als Rückgabewert einen Zeiger auf den neuen String.
char* addString(char *string, char *addString) { char *newString; /* Zeiger auf den neune String */ int i, j, k, length; /* Iteratoren */ /* Länge das Originalstrings ermitteln */ for(i=0; string[i] != 0; i++); /* Länge des hinzuzufügenden Stings ermitteln */ for(j=0; addString[j] != 0; j++); j++; /* Plus dem 0 (ende) Zeichen */ length = j + i; /* Länge des neuen Strings */ /* Neuen Sting im Speicher erzeugen */ newString = (char*)malloc(length*sizeof(char)); /* Falls fehlschlägt gebe NULL zurück */ if(newString==NULL) return NULL; /* Neune String mit altem füttern */ for(k=0; k<i; k++) { newString[k] = string[k]; } /* Neuen String mit zuzufügendem füttern */ for(i=0; k<length-1; k++, i++) { newString[k] = addString[i]; } k++; /* String mit 0 abschließen */ newString[k] = 0; /* Alten String freigeben ? */ /* Wird dadurch der ganze sting frei gegeben, ich bin mir nicht sicher ? */ free(string); /* Zeiger auf den neune String zurückgeben */ return newString; } int main() { char *c; /* Initialisieren mit 0 */ c = (char*)malloc(sizeof(char)); *c = 0; c = addString(c, "Hallo "); c = addString(c, "Welt!"); printf("%s\n", c); return 0; }
Kann man das überhaupt so machen wie ich mir das hier vorstelle oder? Wie gesagt es geht nur in einem Win32 Projekt nicht
Danke wenn mir da jemand weiterhelfen kann!
mfg Bernhard
-
1. dein code ist grauenhaft und erzeugt Speicherlecks. Pro malloc ein free und das hast du nicht. Um dynamischen Speicher nachträglich zu verändern gibt es man: realloc(3).
2. malloc castet man nicht (wie oft am Tag sollen wir denn das sagen?)
3. ein C String muss 0-terminierend sein, d.h. du musst für n Zeichen mind. n+1 Bytes reservieren
4. sizeof(char) ist immer 1
5. memcpy kopiert einen Block, du brauchst keine for-Schleife zum Kopieren.
Guck dir das hier an: http://www.c-plusplus.net/forum/viewtopic-var-t-is-191078-and-start-is-20.html
zwar nicht dasselbe, was du wolltest, aber im wesentlichen genau dieselben Verfahren.
-
Danke für den Tipp mit realloc(), das war genau das was ich gebraucht habe!
Hab das jetzt so gelöst, und es funktioniert:
char* stringExtend(char *string, char *string2) { size_t newLength; size_t len1, len2; int i, j; len1 = stringLength(string); len2 = stringLength(string2); newLength = len1 + len2 + 1; string = realloc(string, newLength); for(i=len1, j=0; i<(newLength-1); i++, j++) { string[i] = string2[j]; } string[newLength-1] = 0; return string; }
-
Arnobaer schrieb:
char* stringExtend(char *string, char *string2) { size_t newLength; size_t len1, len2; int i, j; len1 = stringLength(string); len2 = stringLength(string2); newLength = len1 + len2 + 1; string = realloc(string, newLength); for(i=len1, j=0; i<(newLength-1); i++, j++) { string[i] = string2[j]; } string[newLength-1] = 0; return string; }
geht viel kürzer...
char* stringExtend(char *string, char *string2) { char *new = realloc (string, strlen(string)+strlen(string2)+1); if (new) strcat (new, string2); return new; }
-
Danke für den tipp! Das is wirklich schöner schlanker code
*uff* hab doch glatt vergessen das es sowas wie strlen() gibt
-
Ein malloc castet man nicht. Was ist daran falsch? Wieso sollte man es nicht casten?
char buf;
buf = (char)malloc(2);
was ist an dem (char*) falsch?danke für die aufklärung
-
Es ist nicht falsch, kann aber in C89 ein mögliches Problem verbergen:
Wenn Du den passenden Header stdlib.h nicht einbindest, nimmt der Compiler an malloc gäbe ein int zurück, das ist eine Regel von C89. Die Umwandlung dieses int in char* würde er Dir ohne Cast mit einer Meldung quittieren, damit weisst Du dass "etwas nicht stimmt" und kannst Maßnahmen einleiten. Mit dem Cast jedoch sagst Du dem Compiler "mir egal, was da zurückkommt, ich bin sicher dass ich es als Zeiger interpretieren möchte" und er warnt Dich nicht.
Wenn stdlib.h aber eingebunden ist, weiss der Compiler dass malloc ein void* zurückgibt, und ein void* kann ohne Cast jederzeit in ein char* gewandelt werden, ohne dass der Compiler warnen müsste.
-
Dann muss supertux ja nicht so reagieren
danke.