Wo liegt hier der Fehler: Funktion ersetzte String im String-Buffer
-
Hallo, ich hab mir eine kleine Funktion geschrieben um einen String beliebiger Länge in einem Char-Buffer gegen einen anderen String beliebiger Länge auszutauschen.
Leider schein da etwas mit dem malloc in der Funktion testfunction nicht zu stimmen, wenn ich den Speicher mit dem Wert allociere den ich rechnerisch für den Buffer brauche crasht das Programm, nehme ich jedoch einen Wert der weit über dem benötigten Speicherbedarf liegt klappt es. Es handelt sich dabei um die Zeilen:real_lenght = buffersize + anzahl*(strlen(string2) - strlen(string1)) + 1; //benötigte Länge + 1 // new_buffersize = real_lenght + 1; //so geht's nicht new_buffersize = buffersize + 10*anzahl*strlen(string2) + 1; //ich weiss net warum, aber so geht's
Ich poste hier mal meinen kompletten Sourcecode, d.h. wer möchte kann das Ganze kompilieren so wie es ist und sich den Fehler anschauen.
Möglicherweise mache ich auch irgendwo einen Fehler beim Berechnen des benötigten Speichers, oder die Funktionen memset, memcpy und memmove lassen sich so nicht ausführen.
Aber wie bereits gesagt, wenn der Wert von malloc recht groß ist, dann gehts blickt da jemand durch und kann mir helfen, dank schon mal vorab.#include <stdio.h> #include <io.h> #include <stdlib.h> #include <string.h> #include <direct.h> #include <winsock.h> #include <malloc.h> //ermittelt die Größe einer Datei u_long File_GetFileSize(char *filename){ struct _finddata_t hFile; long fHandle; u_long file_size; fHandle = _findfirst(filename, &hFile); if(fHandle == -1){ return 0; }else{ file_size = hFile.size; _findclose(fHandle); return file_size; } } //läd den Inhalt einer Datei in einen Datenpuffer int File_LoadBinaryFile(char *filename, u_char *databuffer, int buffersize){ FILE *datei; int len; datei = fopen(filename,"rb"); if(!datei){ return 0; } len = fread(databuffer, buffersize, 1, datei); fclose(datei); return File_GetFileSize(filename); } /* method 0 : der Platzbedarf wird ermittelt method 1 : der String wird ausgetauscht */ int String_ChangeString(u_char *buffer, u_char *oldString, u_char *newString, int len_buffer, int len_oldString, int len_newString, int method){ int i, j, replace_counter = 0, tmp_counter; for(i = 0; i < len_buffer; i++){ if(*(buffer + i) == *(oldString)){ if(len_oldString == 1){ tmp_counter = len_oldString; }else{ tmp_counter = 1; for(j = 1; j < len_oldString; j++){ if(*(buffer + i + j) == *(oldString + j)){ tmp_counter++; }else{ break; } } } if(tmp_counter == len_oldString){ replace_counter++; if(method == 1){ memmove((buffer + i), (buffer + i + len_oldString), (len_buffer - i - len_oldString)); memset((buffer + i + len_buffer - len_oldString), 0, len_oldString); len_buffer -= len_oldString; memmove((buffer + i + len_newString), (buffer + i), (len_buffer - i)); memcpy((buffer + i), newString, len_newString); len_buffer += len_newString; i += (len_newString - 1); }else{ i += (len_oldString - 1); } } } } return replace_counter; } void testfunction(u_char *buffer, int buffersize){ int anzahl, new_buffersize, real_lenght; u_char *buffer2; char string1[256], string2[256]; strcpy(string1, "buffer"); strcpy(string2, "123 blabla"); anzahl = String_ChangeString(buffer, string1, string2, buffersize, strlen(string1), strlen(string2), 0); //Anzahl der Ersetzungen ermitteln printf("anzahl: %i\n", anzahl); if(anzahl == 0){ return; } if(strlen(string1) < strlen(string2)){ real_lenght = buffersize + anzahl*(strlen(string2) - strlen(string1)) + 1; //benötigte Länge + 1 // new_buffersize = real_lenght + 1; //so geht's nicht new_buffersize = buffersize + 10*anzahl*strlen(string2) + 1; //ich weiss net warum, aber so geht's printf("\nnew_buffersize: %i\n", new_buffersize); buffer2 = malloc(new_buffersize); if(buffer2){ memset(buffer2, 0, new_buffersize); memcpy(buffer2, buffer, buffersize); anzahl = String_ChangeString(buffer2, string1, string2, real_lenght, strlen(string1), strlen(string2), 1); *(buffer2 + real_lenght) = '\0'; printf(buffer2); printf("\nAnzahl: %i\n", anzahl); free(buffer2); }else{ printf("Error: can't malloc buffer2\n"); } }else{ anzahl = String_ChangeString(buffer, string1, string2, buffersize, strlen(string1), strlen(string2), 1); printf(buffer); printf("\nAnzahl: %i\n", anzahl); } } int main(int argc, char *argv[]){ int back = 0; char filename[1024]; u_char *filebuffer; u_long filesize; strcpy(filename, "main.c"); filesize = File_GetFileSize(filename); if(filesize != 0){ filebuffer = malloc(filesize); if(filebuffer){ File_LoadBinaryFile(filename, filebuffer, filesize); testfunction(filebuffer, filesize); free(filebuffer); }else{ printf("Error: can't malloc filebuffer\n"); back = -1; } }else{ printf("Error: file with size 0 found\n"); back = -1; } getchar(); return(back); }
-
Also, ich weiß nicht ganz genau, was du damit bezweckst, aber ich denke das Problem liegt in Zeile 67:
memset((buffer + i + len_buffer - len_oldString), 0, len_oldString);
Dort langst Du (nach meinem Debugging) über Deine Buffergrenze hinaus und setzt einen nicht allokierten Speicherbereich zu Null.
Außerdem schiebst Du in Zeile 69:
memmove((buffer + i + len_newString), (buffer + i), (len_buffer - i));
wieder über das Speicherende hinaus, so wie ich das sehe.
Insgesamt denke ich, das ist zu kompliziert. Warum schiebst Du hin und her, du musst doch bloss den hinteren Teil des Buffers um strlen(string2) - strlen(string1) verschieben und das andere überschreiben.
Ich hoffe, ich erzähle jetzt nicht den totalen Käse, habe leider nicht besonders viel Zeit, um das anzuschauen.
-
Danke für die Antwort, du hast mich in die richtige Richtung geschubst. Mit Zeile 67 hast du recht gehabt, das hab ich echt übersehen, ich hab deinen Rat befolgt und es komplett anderst gemacht. Zeile 65 -75 sieht nun so aus:
if(method == 1){ if(len_newString != len_oldString){ memmove((buffer + i + len_newString), (buffer + i + len_oldString), (len_buffer - i - len_oldString)); len_buffer += (len_newString - len_oldString); } memcpy((buffer + i), newString, len_newString); i += (len_newString - 1); }else{ i += (len_oldString - 1); }
bei ehemals Zeile 69 gebe ich dir auch recht, insofern daß der Aufruf der Funktion String_ChangeString mit der falschen Länge erfolgte
falsch (Zeile 104):
anzahl = String_ChangeString(buffer2, string1, string2, real_lenght, strlen(string1), strlen(string2), 1);
dies sollte richtig sein (Zeile 104):
anzahl = String_ChangeString(buffer2, string1, string2, buffersize, strlen(string1), strlen(string2), 1);
ich glaube jetzt gehts, aber vieleicht findest du nochmals die Zeit drauf zu schauen.