realloc():重新分配时为下一个大小无效,为char *上的strcat腾出空间
我在以下代码上收到无效的内存错误:
printf(" %s\n","FINE 5"); printf("%s LENGTH IS: %d\n","FINE 6",strlen(": ")); buffer = (char *)realloc(buffer, strlen(buffer)* sizeof(char) + (strlen(": ")+1)* sizeof(char)); printf(" %s\n","FINE 7"); strcat(buffer, ": \0");
输出:
精细5
精细6长度是:2
*检测到glibc * ./auto:realloc():下一个大小无效:0x08cd72e0 *** ======= Backtrace:========= /lib/tls/i686/cmov/libc.so 0.6(+ 0x6b591)[0x6dd591]
这里需要注意的是Fine 7
从未打印过。 每次运行时无效的下一个大小错误位于同一位置。
发现这种相关性
发生此错误是因为代码的某些其他部分已损坏堆。 如果没有看到其余代码,我们无法告诉您错误是什么。
未打印FINE 7
的事实告诉您realloc
失败。 并且该失败必须是因为buffer
由于执行中较早的堆损坏而无效。
与您的实际问题正交, sizeof(char)
的定义是1
,因此从代码中删除它是有意义的。
正如David Heffernan指出的那样,你的根问题必须是代码中其他地方的一个狂野指针。
不过,在这段代码中还有其他一些值得考虑的事情:
-
新大小表达式中不需要sizeof(char),因为sizeof(char)根据定义为1。
-
永远不要将realloc的返回值直接返回到指向要重新分配的缓冲区的唯一指针。 如果realloc在错误上返回NULL,您将丢失指向旧缓冲区的指针,并获得自己的内存泄漏。 你总是想做相应的:
footype *p = realloc(oldbuff, newsize); if (!p) { handle_error(); } else { oldbuff = p; }
-
在C中,void *将在赋值时自动转换为正确的类型,不需要强制转换。 此外,通过强制转换,在某些情况下,当您忘记包含相关函数的声明时,您将不会收到有用的错误消息。
-
字符串文字包括隐含的nul终止符。 你想说:
strcat(buffer,“:”);
从好的方面来说,strcat会在第一个nul字符处停止,所以在这种情况下没有坏处。
(char *)realloc(buffer, strlen(buffer)* sizeof(char) + (strlen(": ")+1)* sizeof(char));
应该
(char *)realloc(buffer, (strlen(buffer) + strlen(": ") + 1) * sizeof(char));
不应该吗? 你是数学的字符串的长度是错误的。