我对这段代码有一些问题,我修改了很多次(但总是出现错误): 它似乎在释放“过滤器”的最后一个索引
时出错0x1521030
HOME
0x1521050
2
0x1521070
A
0x1521010
8
0x15210c0
D
*** Error in `./test': free(): invalid pointer: 0x00000000015210c0 ***
这是输出:
{{1}}
我也尝试用valgrind调试它(它告诉我分配器试图释放9个字节,而字符总和是8,奇怪没有?)和gdb但没有任何效果。 input.txt的第一行是“HOME 2 A 8 D \ n”
答案 0 :(得分:7)
第一次执行这些行
bufs = realloc(bufs, (j+1)*sizeof(char*));
bufs[j++] = strndup(buf,len);
你获得1个指针的内存(j为0)。这为您在
函数末尾写入的结束NULL
留下了空间
bufs[j] = 0;
所以你写的是超出分配的内存,因此有未定义的行为。同样,每次延长缓冲区长度。
答案 1 :(得分:6)
bufs[j] = 0;
末尾的read_and_filter
写入未分配的内存。您永远不会realloc
- 为您的bufs
添加0
。
答案 2 :(得分:0)
内存泄漏发生在两个地方 - strdup和realloc
一个答案是使用malloc在main中为缓冲区初始分配内存,然后将指针传递给分配的内存到函数。然后,该函数可以重新分配缓冲区,并将数据复制到其中。
从函数返回时,main可以直接从缓冲区访问数据,因为它有一个有效的指针,然后可以在关闭之前释放该内存。
据valgrind说,以下没有记忆丧失。
void read_and_filter(int fd, char **bufs) {
char buf[100];
char ch;
int j = 0, len = 0, t = 0;
while (!t && read(fd,&ch,1) == 1) {
switch (ch) {
case '\n':
t = 1;
case ' ':
*bufs = realloc(*bufs, (j + 2)*sizeof(char*));
strncpy(bufs[j++], buf, len);
memset(buf,0,len);
len = 0;
break;
default:
buf[len++] = ch;
}
}
bufs[j] = 0;
return;
}
int main(int argc, char **argv) {
char *bptr = malloc(1);
int fd = open("input.txt", O_RDONLY);
read_and_filter(fd, &bptr);
printf("%s\n", bptr);
free(bptr);
return 0;
但是我不能确定这完全复制了OP的预期功能,但整体方法确实解决了内存问题。