c语言 - 操纵指针导致瓦尔格林德"invalid realloc()"



我有一个项目,它涉及读取数量不确定的字符串,并根据一些相关的元数据将它们附加到不同的char**中。我有一段代码将realloc((一个char**与数据一起动态增长,它将一个指向其中一个char***的指针作为输入,因此它可以有点通用。然而,我在指针上搞砸了一些东西,导致realloc((过早地释放((char**,从而导致错误。我找不出我做错了什么。

这是一个精简的示例,说明了我要做的事情。对元数据的引用被剥离,相反,代码在一个字符**和另一个字符之间交替,这种方式可能会在整个项目中发生。此示例还省略了malloc((上的一些错误检查和完整项目中可能存在的一些适当的清理(即free(((。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print_elems(char **array, int length) {
for (int i = 0; i < length; i++) {
printf("%s", array[i]);
}
}
void main() {
char **array = (char**) malloc(sizeof(char*));
int length = 1;
int index = 0;
char **array2 = (char**) malloc(sizeof(char*));
int length2 = 1;
int index2 = 0;

char **pointarray = array2;
int* pointlen = &length2;
int* pointidx = &index2;
char newelem[10];
while(1) {
printf("Enter a string: ");
fgets(newelem, 10, stdin);
pointarray = (pointarray == array2 ? array : array2);
pointlen = (pointlen == &length2 ? &length : &length2);
pointidx = (pointidx == &index2 ? &index : &index2);
if (*pointlen == *pointidx) {
printf("Resizing array...n");
void* newarray = realloc(pointarray, sizeof(char*)*(*pointlen+1));
if (pointarray == NULL) {
perror("Error allocating memory.n");
exit(1);
} else {
pointarray = (char**) newarray;
}
(*pointlen)++;
}
pointarray[*pointidx] = strdup(newelem);
(*pointidx)++;
print_elems(pointarray, *pointlen);
}
}

通常,在循环中运行不超过10次后,程序就会崩溃。Valgrind给出以下输出:

==11278== Invalid free() / delete / delete[] / realloc()
==11278==    at 0x483AD19: realloc (vg_replace_malloc.c:836)
==11278==    by 0x4012EA: main (test.c:38)
==11278==  Address 0x4a23090 is 0 bytes inside a block of size 8 free'd
==11278==    at 0x483AD19: realloc (vg_replace_malloc.c:836)
==11278==    by 0x4012EA: main (test.c:38)
==11278==  Block was alloc'd at
==11278==    at 0x483880B: malloc (vg_replace_malloc.c:309)
==11278==    by 0x401215: main (test.c:17)
==11278== 
==11278== Invalid write of size 8
==11278==    at 0x401345: main (test.c:48)
==11278==  Address 0x10 is not stack'd, malloc'd or (recently) free'd

如果我不做所有这些指针切换程序运行良好,但项目会更加复杂,我必须想象有一种方法可以做我想做的事情。

有人能告诉我我搞砸了什么让realloc((偏离轨道吗?

调用realloc()后,将结果分配给pointarray,但这不会更改arrayarray2。然后,在未来的迭代中,将其中一个分配给pointarray,但它们不再指向有效的存储。

您需要一个额外的间接级别,类似于间接获取长度和索引变量的方式。

此外,在您呼叫realloc()之后,您正在检查pointarray,但您应该检查newarray

void main() {
char **array = malloc(sizeof(char*));
int length = 1;
int index = 0;
char **array2 = malloc(sizeof(char*));
int length2 = 1;
int index2 = 0;
char ***pointarray = array2;
int* pointlen = &length2;
int* pointidx = &index2;
char newelem[10];
while(1) {
printf("Enter a string: ");
fgets(newelem, 10, stdin);
pointarray = (pointarray == &array2 ? &array : &array2);
pointlen = (pointlen == &length2 ? &length : &length2);
pointidx = (pointidx == &index2 ? &index : &index2);
if (*pointlen == *pointidx) {
printf("Resizing array...n");
void* newarray = realloc(*pointarray, sizeof(char*)*(*pointlen+1));
if (newarray == NULL) {
perror("Error allocating memory.n");
exit(1);
} else {
*pointarray = newarray;
}
(*pointlen)++;
}
(*pointarray)[*pointidx] = strdup(newelem);
(*pointidx)++;
print_elems(*pointarray, *pointlen);
}
}

最新更新