地址 0x0 未被堆栈、malloc 或(最近)释放 [英] Address 0x0 is not stack'd, malloc'd or (recently) free'd
问题描述
我对 C 很陌生,似乎无法弄清楚以下代码有什么问题.
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 给我这个错误:
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 对应于以 fputs 开头的行,直到此代码的末尾.
repl.c corresponds to the line beginning with fputs toward the end of this code.
此外,mychars 是一个二维数组,如下所示:
Also, mychars is a two dimensional array that looks like this:
char *mychars[NUM][2] = {
"a", "97",
"b", "98",
....
谁能告诉我如何解决这个问题?此外,任何有关我应该如何改进当前代码(尤其是使用 malloc)的指示都将不胜感激.
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.
str_replace 的代码
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 str_replace 和 main 的新代码
EDIT 2 New Code for str_replace, and main
出于测试目的,我用此处找到的方法替换了我的 str_replace 方法:
For testing purposes, I've replaced my str_replace method with the one found here:
我的主要内容略有变化:
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;
}
但我仍然得到
==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.
编辑 3我已经更新了 for 循环中心的代码:
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);
}
现在我开始输出了!但是,仅在两次迭代之后,我就遇到了分段错误,valgrind 给了我一大堆这样的错误:
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
推荐答案
这两行
result = (char *) malloc (sizeof(char) * 128);
result = str_replace(line, rep, with);
您首先为 result
分配空间,然后通过返回 str_replace
覆盖它,然后立即释放空间.该函数可能返回 0
,因此您的 fputs
失败.
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.
顺便说一句,不要强制转换 malloc
的返回值,在 C 中这是多余的,可能会隐藏您忘记包含原型的事实.
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.
您的 str_replace
函数在其内存处理方面完全错误.永远不要返回指向局部变量的指针,离开函数后该空间无效.
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.
这篇关于地址 0x0 未被堆栈、malloc 或(最近)释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!