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指出的那样,你的根问题必须是代码中其他地方的一个狂野指针。

不过,在这段代码中还有其他一些值得考虑的事情:

  1. 新大小表达式中不需要sizeof(char),因为sizeof(char)根据定义为1。

  2. 永远不要将realloc的返回值直接返回到指向要重新分配的缓冲区的唯一指针。 如果realloc在错误上返回NULL,您将丢失指向旧缓冲区的指针,并获得自己的内存泄漏。 你总是想做相应的:

     footype *p = realloc(oldbuff, newsize); if (!p) { handle_error(); } else { oldbuff = p; } 
  3. 在C中,void *将在赋值时自动转换为正确的类型,不需要强制转换。 此外,通过强制转换,在某些情况下,当您忘记包含相关函数的声明时,您将不会收到有用的错误消息。

  4. 字符串文字包括隐含的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));

不应该吗? 你是数学的字符串的长度是错误的。