17

我在以下代码中收到无效的内存错误:

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");

输出:

FINE 5
FINE 6 LENGTH IS: 2
* glibc detected * ./auto: realloc(): invalid next size: 0x08cd72e0 *** ======= Backtrace: ========= /lib/tls /i686/cmov/libc.so.6(+0x6b591)[0x6dd591]

这里要注意的一点Fine 7是从不打印。每次运行时无效的下一个大小错误都在同一位置。

找到这个相关的

4

3 回答 3

17

发生此错误是因为您的代码的某些其他部分已损坏堆。如果不查看其余代码,我们无法告诉您该错误是什么。

FINE 7未打印的事实告诉您这realloc是失败的。并且该失败必须是因为buffer在执行早期由于堆损坏而无效。


根据定义,与您的实际问题正交,sizeof(char)因此1将其从代码中删除是有意义的。

于 2011-12-08T20:10:35.987 回答
9

正如 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(缓冲区,“:”);

从好的方面来说, strcat 将在第一个 nul 字符处停止,所以在这种情况下没有害处。

于 2011-12-08T20:11:56.090 回答
0

(char *)realloc(buffer, strlen(buffer)* sizeof(char) + (strlen(": ")+1)* sizeof(char));

应该

(char *)realloc(buffer, (strlen(buffer) + strlen(": ") + 1) * sizeof(char));

不应该吗?您对字符串长度的数学计算是错误的。

于 2011-12-08T20:12:04.327 回答