为何malloc分配的arr1的sizeof结果小于arr2?与栈堆有关吗?
指针与变长数组的sizeof结果差异原因解析
核心结论
sizeof(arr1)和sizeof(arr2)的差异本质是两者类型完全不同:arr1是指针变量,arr2是变长数组类型,栈堆存储位置是关联特性,但直接原因是类型决定了sizeof的计算逻辑。
1. 为什么arr1的结果是8字节
arr1的定义是int *arr1,从始至终它的类型都是整型指针。不管它指向堆内存(malloc分配的区域)还是栈内存(arr2的地址),指针变量自身的大小只和系统位数有关:64位系统下指针固定占8字节,32位系统下占4字节。- 执行
arr1 = arr2;只是改变了指针的指向,并没有改变arr1本身的类型,所以sizeof(arr1)计算的是指针变量自己的字节数,和它指向的数组大小无关。 - 注意:代码中
malloc分配的堆内存已经丢失,因为arr1被重新赋值后,没有任何变量保存原来的堆地址,造成了内存泄漏。
2. 为什么arr2的结果是16字节
arr2是变长数组(VLA),它的长度由运行时的length变量决定(这里是4)。C标准规定,变长数组的sizeof会在运行时计算整个数组的总字节数:4个int元素 × 每个int4字节 = 16字节。- 变长数组存储在栈上,malloc分配的内存在堆上,这是两者存储位置的区别,但不是sizeof结果不同的直接原因——就算是堆上的动态数组,用指针指向它时,
sizeof(指针)依然是指针大小,而非数组大小。
3. 元素打印正常的原因
打印元素正常是因为arr1现在指向arr2的首地址,通过指针下标访问arr1[i]等价于*(arr1+i),这是指针访问数组的标准逻辑,和sizeof的计算规则完全独立。
补充说明
如果想通过arr1获取它指向的数组大小,无法直接用sizeof实现,因为指针本身不携带数组长度信息。你需要自己额外保存数组长度(比如用变量length),或者使用结构体封装指针和长度。
内容的提问来源于stack exchange,提问作者Om Deore
相关产品推荐
相关产品推荐

