在C语言中如何找到malloc()分配的数组长度?

25

可能重复:
如何查找指向数组的指针的大小

我正在学习如何在C语言中创建动态数组,但遇到了一个问题,我无法解决。

如果我使用以下代码:

int num[10];
for (int i = 0; i < 10; i++) {
    num[i] = i;
}
printf("sizeof num = %li\n sizeof num[0] = %li", sizeof(num), sizeof(num[0]));

我得到了输出:

sizeof num = 40
sizeof num[0] = 4

这是我期望发生的事情。不过,如果我像这样分配数组的大小:

int *num;
num = malloc(10 * sizeof(int));
for (int i = 0; i < 10; i++) {
    num[i] = i;
}
printf("sizeof num = %li\n sizeof num[0] = %li", sizeof(num), sizeof(num[0]));

然后我得到输出:

sizeof num = 8
sizeof num[0] = 4

当我使用固定长度方法时,数组大小为40,但是我使用malloc()时不是这样,我很好奇为什么。


在第二种情况下,num 是一个指向 int 的指针,其大小取决于机器,即在32位系统中为4个字节,在64位系统中为8个字节。而在第一种情况下,num 不是指针,它是数组的“基地址”,所以sizeof()会给出整个数组的总大小。 - krpra
4个回答

33
在第二种情况下,num 不是一个数组,而是一个指针。 sizeof 给出的是指针的大小,在您的平台上似乎为8个字节。
无法知道动态分配数组的大小,你必须在其他地方保存它。 sizeof 查看类型,但你不能从malloc 的结果中获取完整的数组类型(具有指定大小的数组类型,例如类型 int [5]),并且sizeof 参数不能用于不完整的类型,如 int[]

你知道free函数的工作原理,编译器或操作系统会记录/跟踪堆分配的块,只需提供指针即可释放,不需要num的数量,那么为什么编译器供应商可以向用户提供从堆记录中检索此num的功能呢?既然已经存在...每当用户调用free(ptr)时。 - Buddhika Chaturanga
@BuddhikaChaturanga 对不起,我不确定我是否理解正确:您是在问为什么实现不公开有关堆分配的内存块的详细信息吗?比如,给定一个指针获取信息? - effeffe
1
是啊...如果他们已经有关于动态分配数据的信息,那么如果他们用它来释放内存,为什么不能提供给用户(开发者)获取这样的信息的功能呢... :) - Buddhika Chaturanga
@BuddhikaChaturanga 如果一个实现暴露了这些细节,那么它们将成为其接口的一部分,他们将无法在未来自由更改。此外,您还可以拥有指向已分配内存块中间的指针:在这种情况下,您会怎么做? - effeffe

5

数组不是指针(在某些情况下可以衰变成指针,但这里不是)。

第一个是数组-因此sizeof给出了40字节的数组大小。

第二个是指针(无论它指向多少元素)- sizeof给出了 sizeof(int*)


2

“第二个大小”是指指针的大小,在您的计算机上,可能是64位,也就是8字节。

您不能使用 sizeof() 恢复动态分配结构的大小,但可以对静态分配的结构执行此操作。


2
如果你想知道你所分配的某个东西的大小,那么你需要自己“记住”,因为你的代码进行了分配。如果你的代码没有进行分配,那么就没有办法[在标准意义下]找出指针所指向的内存有多大。你只能通过其他方式“知道”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接