2
int length = 5;
int hi[length];

对比

int length = 5;
int *hi = new int[length];

每当您尝试静态分配大小不恒定的数组时,我都被告知编译器会在 C 中抱怨。因此,如果您需要未知大小的数组,则需要动态分配内存。但是,既然有允许第一个示例的编译器,那么它们到底在做什么呢?他们仍然在数据段中,还是不在堆中?如果它们在堆上,那么示例之间有什么区别,为什么我仍然必须在第二个示例中调用 delete[] 而不是第一个示例?

4

2 回答 2

2

但是,既然有允许第一个示例的编译器,那么它们到底在做什么呢?他们仍然在数据段中,还是不在堆中?如果它们在堆上,那么示例之间有什么区别,为什么我仍然必须在第二个示例中调用 delete[] 而不是第一个示例?

第一个是声明一个静态变量(通常在堆栈上*),它将在定义它的代码块的末尾死亡。

第二个是动态分配一个变量(通常在堆*上),这意味着您可以决定在哪里释放它delete[](是的,您应该记住这样做)。

在数组上下文中,两者之间的主要区别在于,第二个可以通过解除分配它指向的内存(例如前一个数组)并使其指向仍然动态分配的新数组来轻松调整大小。

int* arr = new int[5];
[...]
delete[] arr;
arr = new int[10];

静态数组int hi[length]通常声明const int*不应修改的 a 。也就是说,C++ 提供了一整套可以/应该使用的容器来代替数组。

[*]注意:C++ 标准没有指定在哪里分配动态或静态内存。

于 2013-03-27T04:02:08.383 回答
0

大概是你的代码

int length = 5;
int hi[length];

是在本地范围内,而不是在文件范围内,因为后者是不合法的。

他们还在数据段中吗

他们永远不会进入数据段;他们进入堆栈(在典型/常见的实现中;语言标准没有说明他们去哪里)。

为什么我仍然必须在第二个示例中调用 delete[] 而不是第一个示例?

首先,VLA(像 的可变长度数组hi[length])在 C++ 中是不合法的,所以你不能调用 delete[]。但是没有必要调用 delete,因为hi在它所在的块的末尾超出了范围。由newOTOH 分配的对象或数组在删除之前不会超出范围。只有指针hi超出范围,但您可能已将其值分配给仍在范围内的另一个指针。

于 2013-03-27T04:01:18.690 回答