简体   繁体   English

realloc有什么问题?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM