Address 0x0 is not stack'd, malloc'd or (recently) free'd

匿名 (未验证) 提交于 2019-12-03 00:50:01

问题:

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 

回答1:

In these two lines

            result = (char *) malloc (sizeof(char) * 128);             result = str_replace(line, rep, with); 

you first allocate space for result that you then loose immediately after by overwriting it with the return of str_replace. That function probably returns 0, so your fputs fails.

BTW, don't cast the return of malloc, in C this is superfluous and may hide the fact that you forgot to include the prototype.

Edit: Your str_replace function is completely wrong in its memory handling. Never return the pointer to a local variable, the space isn't valid after you have left the function.



回答2:

If NUM is 0, then result is uninitialized and may be 0 by chance.

You aren't checking the results of your calls to malloc(), so a failure can mean you're trying to write to a NULL pointer.

Where is mychars declared?



回答3:

You don't show how mychars is declared, but this line:

rep = (char *) malloc (sizeof(mychars[i][0])) 

looks like it probably only allocates one byte. Also you're allocating a lot of memory and never freeing it. And here:

result = (char *) malloc (sizeof(char) * 128); result = str_replace(line, rep, with); 

You allocate memory using malloc and then completely discard the pointer to that memory by assigning the return value of another function over the top of it.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!