I'm very new to C, and can't seem to figure out what's wrong with the following code.
int main() { char filen[] = "file.txt"; FILE *file = fopen ( filen, "r" ); if ( file != NULL ) { char line [ 128 ]; while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */ { int i; char *result; for(i=0; i< NUM;i++) { char *rep; rep = (char *) malloc (sizeof(mychars[i][0])); strcpy(rep, mychars[i][0]); char *with; with = (char *) malloc (sizeof(mychars[i][1])); strcpy(with, cgichars[i][1]); result = (char *) malloc (sizeof(char) * 128); result = str_replace(line, rep, with); } fputs(result, stdout); } } fclose ( file ); return 0; }
Valgrind is giving me this error:
==4266== Invalid read of size 1 ==4266== at 0x4C286D2: __GI_strlen (mc_replace_strmem.c:284) ==4266== by 0x5118A8D: fputs (iofputs.c:37) ==4266== by 0x400A0F: main (repl.c:35) ==4266== Address 0x0 is not stack'd, malloc'd or (recently) free'd
repl.c corresponds to the line beginning with fputs toward the end of this code.
Also, mychars is a two dimensional array that looks like this:
char *mychars[NUM][2] = { "a", "97", "b", "98", ....
Can someone please tell me how to fix this? Also, any pointers on how I should improve my current code (especially with malloc) would be much appreciated.
Edit: Code for str_replace
char *str_replace(char *str, char *orig, char *rep) { char buffer[4096]; char *p; if(!(p = strstr(str, orig))) return NULL; strncpy(buffer, str, p-str); buffer[p-str] = '\0'; sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig)); return buffer; }
EDIT 2 New Code for str_replace, and main
For testing purposes, I've replaced my str_replace method with the one found here:
What is the function to replace string in C?
And my main is changed slightly:
int main() { static const char filen[] = "file.txt"; FILE *file = fopen ( filen, "r" ); if ( file != NULL ) { char line [ 128 ]; while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */ { int i; char *result; for(i=0; i< NUM;i++) { char *rep; rep = (char *) malloc (sizeof(mychars[i][0])); strcpy(rep, mychars[i][0]); char *with; with = (char *) malloc (sizeof(mychars[i][1])); strcpy(with, mychars[i][1]); result = str_replace(line, rep, with); } fputs(result, stdout); } } fclose ( file ); return 0; }
But I'm still getting
==6730== Invalid read of size 1 ==6730== at 0x4C286D2: __GI_strlen (mc_replace_strmem.c:284) ==6730== by 0x5118A8D: fputs (iofputs.c:37) ==6730== by 0x400995: main (repl.c:29) ==6730== Address 0x0 is not stack'd, malloc'd or (recently) free'd
Perhaps the most frustrating part of this is not knowing what these Invalid read errors are.
EDIT 3 I've updated the code in the center of the for loop as such:
int i; char* result; result = &line[0]; for(i=0; i< NUM_CGICHARS;i++) { char *rep; rep = (char *) malloc (sizeof(char)); strcpy(rep, cgichars[i][1]); char *with; with = (char *) malloc (sizeof(char)*3); strcpy(with, cgichars[i][0]); result = str_replace(result, rep, with); fputs(result, stdout); free(rep); free(with); }
And now I'm starting to get output! However, after only two iterations, I get a segmentation fault, with valgrind giving me a whole bunch of this:
==9130== Invalid read of size 1 ==9130== at 0x4C286D2: __GI_strlen (mc_replace_strmem.c:284) ==9130== by 0x5118A8D: fputs (iofputs.c:37) ==9130== by 0x4009DF: main (teststep1.c:27) ==9130== Address 0x0 is not stack'd, malloc'd or (recently) free'd