【问题标题】:Program causes memory corruption while reallocating memory程序在重新分配内存时导致内存损坏
【发布时间】:2012-11-12 18:43:15
【问题描述】:

我有一个带有二维数组的程序。首先我像这样分配数组:

char **crossword;
crossword = (char **) malloc(n* sizeof(*crossword));
for (i = 0; i < n; i++)
    crossword[i] = (char *)malloc(n);

其中 n = 50。

然后我就有了从标准输入读取字符串的函数。问题是,我不知道这些字符串会有多少或多长。

void read(char **p,int *n)
{
char tmp = 0,prevtmp = 0;
int i = 0, j = 0,x;

while (1)
{
    prevtmp = tmp;
    tmp = getchar();
    if ((tmp == '\n' && prevtmp == '\n') || feof (stdin))
    {
        *n = i;
        break;
    }
    if (tmp == '\n')
    {
        p[i][j] = '\0';
        i++;
        if (i == *n)
        {
            p = (char **) realloc(p, 2*i); // if there is more strings than space for them, allocate more memory.
            for (x = i; x < 2*i; x++)
                p[x] = (char *) malloc (*n);

            *n *= 2;
        }
        j = 0;
        continue;
    }
    p[i][j] = tmp;
    j++;
    if (j == *n)
        p[i] = (char *)realloc(p[i], 2*j); //same as above
}
}

函数是这样调用的:

read(crossword,&n);

当不需要 realloc(少于 50 个字符串,每个小于 50 个字符)时,此函数可以正常工作。但是对于大输入,这会失败,

*** glibc detected *** ./a.out: malloc(): memory corruption (fast): 0x00000000014282f0 *** error.

我认为我的问题在于我重新分配了更多内存,这里是 valgrind 的输出:

==8885== Invalid write of size 1
==8885==    at 0x40084C: read (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out)
==8885==    by 0x40177F: main (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out)
==8885==  Address 0x51f2b88 is not stack'd, malloc'd or (recently) free'd
==8885== 
==8885== Invalid write of size 8
==8885==    at 0x4008A6: read (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out)
==8885==    by 0x40177F: main (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out)
==8885==  Address 0x51f4f00 is not stack'd, malloc'd or (recently) free'd

valgrind: m_mallocfree.c:266 (mk_plain_bszB): Assertion 'bszB != 0' failed.
valgrind: This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata.  If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away.  Please try that before reporting this as a bug.

==8885==    at 0x3804C6CF: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x3804C812: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x38000883: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x380574EA: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x38057E03: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x380212DC: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x3802146A: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x3808F656: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x3809E68C: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable
==8885==    at 0x4C2B3F8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8885==    by 0x4008A5: read (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out)
==8885==    by 0x40177F: main (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out)

我已经用指针试验了很短的时间,所以我不知道出了什么问题。我一直在尝试解决这个问题几个小时,但我没有想出任何办法。

我做错了什么?

【问题讨论】:

  • 填字游戏的类型是什么?
  • char **填字游戏,编辑了我的帖子。
  • 您在代码中执行此操作p = (char **) realloc(p, 2*i);p 是指填字游戏吗?如果是这样,您已经分配了大小为n * sizeof(*crossword) 的填字游戏。那么2*i 正确吗?顺便说一句,调用 realloc 并将其结果分配给您直接重新分配的指针是不好的 - 如果 realloc() 失败它会泄漏内存,导致您的原始指针现在丢失。
  • 二维数组和双指针不是一回事。在双指针上使用 [][] 总是不好的。请阅读:ibiblio.org/pub/languages/fortran/append-c.html.
  • @linuxuser27 为什么stringArray[i][j] 不能在stringArray[i] 指向的以0 结尾的字符串中获取索引j 处的字符?我发现这比*(*(stringArray + i) + j)*(stringArray[i] + j)(*(stringArray + i))[j] 清楚得多。

标签: c malloc valgrind realloc


【解决方案1】:

问题似乎出在以下行:

p = (char **) realloc(p, 2*i);

我猜应该是:

p = (char **) realloc(p, (2*i)*sizeof(char*));

即您想增加数组以容纳2*i 元素,因此您需要分配2*i 乘以char* 的大小。

【讨论】:

  • 谢谢,解决了这个问题,但我的程序仍然崩溃,这次出现了不同的错误。我现在正在通过电话发帖,我不记得确切的错误,明天早上会调查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-09
  • 1970-01-01
  • 1970-01-01
  • 2015-12-15
  • 1970-01-01
相关资源
最近更新 更多