gpt4 book ai didi

c - 程序在重新分配内存时导致内存损坏

转载 作者:行者123 更新时间:2023-11-30 15:53:39 24 4
gpt4 key购买 nike

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

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

当不需要重新分配时(字符串少于 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)

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

我做错了什么?

最佳答案

问题似乎出在以下行:

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

我想应该是:

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

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

关于c - 程序在重新分配内存时导致内存损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13545370/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com