【发布时间】:2015-11-04 18:18:27
【问题描述】:
我已经验证了可变长度数组是在堆上创建的(参见下面的代码),但我们不能使用空闲操作来释放它们(导致故障陷阱 6)。
我被告知堆是由用户管理的,因此如果我们不需要它们,我们必须显式地释放堆上的任何东西。那么谁来负责释放这些记忆呢?这是C语言的缺陷吗?
显示可变长度数组的代码是在堆上创建的。 (平台:Mac OS X,gcc,64位)
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv)
{
int n = atoi(argv[1]);
int a1[10];
int a2[n];
int a3[10];
printf("address for a1:%p,address for a2:%p, address for a3:%p\n",a1,a2,a3);
printf("a1-a2: %lx, a1-a3: %lx\n",(a1-a2),(a1-a3));
//free(t); // will cause fault trap 6
return 0;
}
结果是:
$ ./run 10
address for a1:0x7fff5d095aa0,address for a2:0x7fff5d0959e0, address for a3:0x7fff5d095a70
a1-a2: 30, a1-a3: c
很明显 a1 和 a3 是连续的,因此在堆栈上,但 a2 的地址较低,因此在堆上。
【问题讨论】:
-
否 - 在这种特殊情况下,VLA 位于堆栈中,但它位于其他局部变量之后(出于显而易见的原因)。但是,无论它位于何处,尝试显式释放它都是错误的。
-
@PaulR Quick,蝙蝠侠,回答问题!
-
“可变长度数组是在堆上创建的”——不。如果你
printf("%p", malloc(1));它可能会从你的静态大小的局部变量和你的 VLA 中产生一个 far away 的地址。 VLA 之前/之后的额外空间可能只是对齐/填充。 -
我投票结束这个问题,因为它是基于一个错误的前提。
-
@Quentin:呵呵——我不确定这个问题是否值得一个完整的答案,因为它基于一个错误的前提(如上所述!),因此可能应该被关闭。