[英]What's wrong with realloc?
Started to learn malloc.h in C. The idea was to create dynamic array. 开始在C学习malloc.h。想法是创建动态数组。 Here is the code: 这是代码:
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
int main() {
int *array = (int*)malloc(sizeof(int));
int i, j, val;
for (i = 0;; i++) {
array = (int*)realloc(array, sizeof(int) + sizeof(*array));
printf("Enter array[%d]=", i);
scanf("%d", (array + i));
if (*(array + i) == 0) break;
}
for (j = 0; j < i; j++) {
printf("[%d] = %d\n", j, *(array + j));
}
getch();
return 0;
}
The result is 结果是
Enter array[0]=1
Enter array[1]=2
Enter array[2]=3
Enter array[3]=4
Enter array[4]=5
Enter array[5]=6
Enter array[6]=7
Enter array[7]=8
Enter array[8]=9
Enter array[9]=10
Enter array[10]=0
[0] = 1
[1] = 2
[2] = 3
[3] = 4
[4] = 5
[5] = 6
[6] = 7
[7] = 8
[8] = 542979931
[9] = 875896893
Each time, >=8
values are random. 每次>=8
值都是随机的。 I have just no idea why it happens so what's wrong? 我不知道为什么会发生这样的错误呢?
You undefined behavior in your code. 您在代码中未定义的行为 。 I suppose, doing this: 我想,这样做:
array=(int*)realloc(array,sizeof(int)+sizeof(*array));
you expect, that sizeof(*array)
will return you the size of the whole array, right? 你期望, sizeof(*array)
会返回整个数组的大小,对吗? But that's not true. 但事实并非如此。 sizeof
is computed at compile time and doing sizeof(*array)
is actually the same as sizeof(int)
. sizeof
在编译时计算,而sizeof(*array)
实际上与sizeof(int)
相同。
So, to make this array extensible, you need to have additional variable, holding the current number of elements and do something like: 因此,要使此数组可扩展,您需要拥有其他变量,保持当前数量的元素并执行以下操作:
array=(int*)realloc(array, sizeof(int) + current_size_of_array * sizeof( int ) );
where current_size_of_array
will be incremented on each loop of the for
, when you actually add one more element. 当你实际添加一个元素时, current_size_of_array
将在for
每个循环上递增。
sizeof(*array)
does not tell you how large the array is. sizeof(*array)
不告诉你数组有多大。 It tells you how many bytes an int occupies. 它告诉你int占用了多少字节。 So each call to realloc is only allocating memory for two int values. 所以每次调用realloc只是为两个int值分配内存。 Change the realloc
call to allocate sizeof(int)
times the number of ints that you want. 更改realloc
调用以将sizeof(int)
分配给所需的sizeof(int)
数。
sizeof(int)+sizeof(*array)
You think that sizeof(*array)
is the number of bytes already allocated. 您认为sizeof(*array)
是已分配的字节数。 You're wrong, sizeof(*array)
is the size of one int
. 你错了, sizeof(*array)
是一个int
的大小。 So you're overrunning your buffer, and eventually that causes you a problem. 所以你超越了你的缓冲区,最终导致你出现问题。
Before you ask, there is no standard way to get the size already allocated. 在你问之前,没有标准的方法来获得已经分配的大小。 Normally you need to store it for yourself (or in C++ use something with a more user-friendly interface than malloc
, such as vector
). 通常你需要为自己存储它(或者在C ++中使用比malloc
更友好的界面,比如vector
)。 In this case, you don't need the existing size, you can work out the new size required from i
. 在这种情况下,您不需要现有的大小,您可以计算出i
所需的新大小。
The size of a block of memory allocated by malloc
is known to the library ( free
only needs the pointer) but there is no portable way to get that number back. 由malloc
分配的malloc
块的大小对于库是已知的( free
只需要指针)但是没有可移植的方法来获取该数字。 You must store in some other variable what is the current size so that you can allocate more space. 您必须在其他变量中存储当前大小,以便分配更多空间。
In sizeof(*array)
the sizeof
operator only considers the type of the expression and in your case is (*(int *))
in other words is the same as sizeof(int)
. 在sizeof(*array)
, sizeof
运算符仅考虑表达式的类型 ,在您的情况下是(*(int *))
,换句话说,与sizeof(int)
相同。
In C++ this work of remembering the number of elements inside a dynamic array allowing increasing the size is done by the standard class std::vector
. 在C ++中,记住动态数组中允许增加大小的元素数量的这项工作是由标准类std::vector
。
As a side note please remember that x = realloc(x, ...);
作为旁注,请记住x = realloc(x, ...);
is a bad idiom because in case of allocation failure your pointer x
would be overwritten by NULL
leaking that memory. 是一个糟糕的习惯用法,因为在分配失败的情况下,你的指针x
会被NULL
泄漏那个内存所覆盖。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.