使用我在这里学到的东西:How to use realloc in a function in C,我写了这个程序。
int data_length; // Keeps track of length of the dynamic array.
int n; // Keeps track of the number of elements in dynamic array.
void add(int x, int data[], int** test)
{
n++;
if (n > data_length)
{
data_length++;
*test = realloc(*test, data_length * sizeof (int));
}
data[n-1] = x;
}
int main(void)
{
int *data = malloc(2 * sizeof *data);
data_length = 2; // Set the initial values.
n = 0;
add(0,data,&data);
add(1,data,&data);
add(2,data,&data);
return 0;
}
该程序的目标是拥有一个动态数组data
,我可以继续添加值。当我尝试向data
添加值时,如果它已满,则使用realloc增加数组的长度。
问题
此程序在运行时编译并且不会崩溃。但是,打印data[0]
,data[1]
,data[2]
会产生0,1,0
。数字2
未添加到数组中。
这是由于我错误地使用了realloc
?
其他信息
此程序稍后将使用不同数量的“添加”和可能的“删除”功能。另外,我知道应该检查realloc
是否失败(是NULL
)但是为了简单起见,这里已经省略了。
我还在学习和试验C.感谢您的耐心等待。
答案 0 :(得分:1)
您无需将data
两次传递给add
。
你可以编码
void add(int x, int** ptr)
{
n++;
int *data = *ptr;
if (n > data_length) {
data_length++;
*ptr = data = realloc(oldata, data_length * sizeof (int));
if (!data)
perror("realloc failed), exit(EXIT_FAILURE);
}
data [n-1] = x;
}
但效率非常低,您应该偶尔拨打realloc
一次。例如你可以
data_length = 3*data_length/2 + 5;
*ptr = data = realloc(oldata, data_length * sizeof (int));
答案 1 :(得分:1)
您的问题在于data
的使用,因为它指向旧数组的地址。然后,当您致电realloc
时,此区域将被释放。因此,您试图在下一条指令上访问无效地址:这会导致未定义的行为。
此外,您不需要使用此data
指针。 test
就足够了。
(*test)[n-1] = x;
答案 2 :(得分:1)
让我们来看看POSIX realloc specification。
描述说:
如果内存对象的新大小需要移动对象,则释放对象先前实例化的空间。
返回值(强调添加)提及:
成功完成后,大小不等于0,realloc()返回指向(可能移动的)分配空间的指针。
您可以检查指针是否发生变化。
int *old;
old = *test;
*test = realloc(*test, data_length * sizeof(int));
if (*test != old)
printf("Pointer changed from %p to %p\n", old, *test);
这种可能的更改可能会严重影响,因为您的代码通过两个不同的名称data
和*test
引用“相同”内存。如果*test
发生更改,data
仍会指向旧的内存块。