5

开始在 C 中学习 malloc.h。想法是创建动态数组。这是代码:

#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;
}

结果是

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

每次,>=8值都是随机的。我只是不知道为什么会发生,所以有什么问题?

4

4 回答 4

7

您在代码中未定义的行为。我想,这样做:

array=(int*)realloc(array,sizeof(int)+sizeof(*array));

您期望,这sizeof(*array)将返回整个数组的大小,对吗?但事实并非如此。sizeof是在编译时计算的,doingsizeof(*array)实际上与sizeof(int).

所以,为了使这个数组可扩展,你需要有额外的变量,保存当前的元素数量并执行以下操作:

array=(int*)realloc(array, sizeof(int) + current_size_of_array * sizeof( int ) );

当您实际添加一个元素时,wherecurrent_size_of_array将在 的每个循环上递增。for

于 2013-03-29T13:03:27.523 回答
3

sizeof(*array)没有告诉你数组有多大它告诉你一个 int 占用了多少字节。所以每次调用 realloc 只是为两个 int 值分配内存。更改realloc调用以分配sizeof(int)所需的整数倍数。

于 2013-03-29T13:03:09.617 回答
2

sizeof(int)+sizeof(*array)

您认为这sizeof(*array)是已经分配的字节数。你错了,sizeof(*array)是一个的大小int。所以你超出了你的缓冲区,最终导致你出现问题。

在你问之前,没有标准的方法来获得已经分配的大小。通常您需要自己存储它(或者在 C++ 中使用比 更用户友好的界面malloc,例如vector)。在这种情况下,您不需要现有尺寸,您可以从i.

于 2013-03-29T13:03:33.100 回答
1

由库分配的内存块的大小malloc是已知的(free只需要指针),但没有可移植的方法来取回该数字。您必须将当前大小存储在其他变量中,以便分配更多空间。

在运算sizeof(*array)符中sizeof仅考虑表达式的类型,在您的情况下(*(int *)),换句话说与sizeof(int).

在 C++ 中,记住动态数组中允许增加大小的元素数量的工作是由标准类完成的std::vector

作为旁注,请记住这x = realloc(x, ...);是一个不好的习惯用法,因为在分配失败的情况下,您的指针x将被NULL泄漏的内存覆盖。

于 2013-03-29T13:08:58.783 回答