4 回答
TA贡献1847条经验 获得超7个赞
编译器不知道它是一个数组,而是在信任程序员。删除指向intwith 的指针delete []将导致未定义的行为。您的第二个main()示例是不安全的,即使它没有立即崩溃也是如此。
编译器确实必须跟踪需要删除多少个对象。它可以通过过度分配足够的空间来存储数组大小来实现此目的。有关更多详细信息,请参见C ++ Super FAQ。
TA贡献1815条经验 获得超10个赞
到目前为止给出的答案似乎并没有解决一个问题:如果运行时库(不是操作系统,实际上不是)可以跟踪数组中的事物数量,那么为什么我们根本需要delete[]语法?为什么不能使用单个delete表单来处理所有删除?
对此的答案可以追溯到C ++的根源,即C兼容语言(它不再是真正的努力。)Stroustrup的哲学是程序员不必为未使用的任何功能付费。如果他们不使用数组,则不必为每个分配的内存块承担对象数组的费用。
也就是说,如果您的代码只是
Foo* foo = new Foo;
那么分配给它的内存空间foo不应包含支持的数组所需的任何额外开销Foo。
由于仅设置了数组分配来承载额外的数组大小信息,因此您需要告诉运行时库在删除对象时寻找该信息。这就是为什么我们需要使用
delete[] bar;
而不只是
delete bar;
如果bar是指向数组的指针。
对于我们大多数人(包括我自己在内)来说,如今对一些额外的内存字节的烦恼似乎很古怪。但是,在某些情况下,保存几个字节(可能来自大量的内存块)可能很重要。
TA贡献1890条经验 获得超9个赞
是的,操作系统将某些内容保留在“后台”中。例如,如果您运行
int* num = new int[5];
操作系统可以分配额外的4个字节,将分配的大小存储在已分配内存的前4个字节中,并返回偏移量指针(即,它将内存空间分配为1000到1024,但返回的指针指向1004,位置为1000- 1003存储分配的大小)。然后,当调用delete时,它可以在传递给它的指针之前查看4个字节,以查找分配的大小。
我相信还有其他方法可以跟踪分配的大小,但这是一种选择。
TA贡献1863条经验 获得超2个赞
这与这个问题非常相似,并且包含许多您正在寻找的细节。
但是足以说,跟踪任何这些都不是操作系统的工作。实际上,运行时库或底层的内存管理器将跟踪数组的大小。通常,这是通过在前面分配额外的内存并在该位置存储数组的大小来完成的(大多数使用头节点)。
通过执行以下代码,这在某些实现中是可见的
int* pArray = new int[5];
int size = *(pArray-1);
添加回答
举报