- 当您使用
new 和delete[] 当您使用new[] 时,您始终且仅使用delete。切勿混合它们。切勿与 (2) 混合使用。
- 当您进行了经典的 C 分配(如
malloc 或 calloc)时,您始终且仅使用 free。切勿与 (1) 混合。但不要释放使用alloca 分配的内存;)
请注意,在某些情况下,分配或解除分配可以隐藏在函数或其他内容中。例如,有一个非标准的 C 函数可以复制这样的字符串:char *str = strdup("Hello");。在这种情况下,您应该使用free(str),即使您没有手动调用malloc。
因此,如果您在 T t[10] 或 T[] t={a,b,c} 表单上进行声明,则不会取消分配。
int main()
{
int x;
std::cin << x;
T *a = new T;
delete a;
T *b = new T[x];
delete[] b;
T *c = (T*)malloc(x*sizeof(*c)); // Casting is needed in C++ but not in C
free(c);
// No free or delete for these
T d;
T e[10];
// Assuming a, b and c are instances of T or that you have overloaded the
// operator so that you can write T t=a;
// In either case, you should not free nor delete this
T f[] = {a, b, c};
}
在 C 中,您可以使用 VLA:s,例如 int arr[x],其中 x 在编译时是未知的。这在 C++ 中是不可能的。你也不能在这些数组上使用 free。
我不认为你这样做,因为没有新的所以它在堆栈上,但我不能 100% 确定这是正确的。
这是不正确的。该标准没有规定对象应该在堆栈上还是堆上。这取决于编译器,所以实际上发生的事情是编译器通常如何解决任务的问题。
此外,静态分配的内存最终在堆栈上而动态分配的内存最终在堆上的“事实”在大多数情况下都是正确的。当然,这通常是会发生的,但在极少数情况下不会发生这种情况。而且这些事件并没有那么罕见或晦涩难懂,以至于可以忽略不计。全局变量通常不会在堆栈中结束。
因此,是否应该释放/删除内存不是它是否位于堆栈或堆中的问题。这是关于它是如何分配的。
在现代 C++ 中,您很少使用 new、new[]、delete 或 delete[]。相反,您使用智能指针和容器。看看这个链接:
What is a smart pointer and when should I use one? 和 https://en.cppreference.com/w/cpp/container/vector 如果您正在处理旧的遗留 C++,将其重构为现代内存管理可能是一个好主意。如果您将 new-delete 对更改为智能指针,那么您已经保存了一行。如果您更改了new 而没有相应的delete,那么您已经解决了一个错误。
TL;DR
什么时候需要删除 C 风格的数组?
对于T a[n] 的情况(有或没有初始化),你永远不应该这样做。对于T *a = new T[n] 的情况,您应该始终这样做。每当您使用new 时,您都应该在之后使用delete,而不是其他方式。 (这可能有一些罕见的例外。请参阅帖子的其余部分。)
另外,AFIK,“C 样式数组”没有既定定义。就个人而言,我根本不会考虑 T *a = new T[n] 一个数组。我也不会考虑 T *a = malloc(n*sizeof(*a)) 一个数组。原因很简单。指针和数组不是一回事,这适用于 C 和 C++。这个问题是关于 C 的,但也适用于 C++:Is an array name a pointer?