指向新元素和新数组的指针之间的区别?

时间:2019-05-20 12:05:10

标签: c++

在C ++中,下面的代码中的指针p和q有什么区别?

int* p = new int;
int* q = new int[5];

我知道一个为一个int分配新内存,第二个为5个int数组分配内存,但是从根本上说,指向单个int的指针和指向一个int数组的指针之间有什么区别吗? / p>

我对此表示怀疑,因为我读到必须使用delete[] q释放q指向的内存,而对于{p1指向的单个int只能释放delete p。 如果我使用delete q会怎样?

3 个答案:

答案 0 :(得分:18)

指针本身是完全无法区分的。这就是为什么必须记住匹配new / deletenew[] / delete[]的原因。

不匹配它们会触发不确定的行为。

答案 1 :(得分:4)

使用new []时,某些c++实现会在指针返回之前跟踪地址中数组的分配大小。这是标准未定义的实现细节。

以下答案更详细地描述了这种可能的实现:How could pairing new[] with delete possibly lead to memory leak only?

您必须始终将newdeletenew []delete []进行匹配。混合这些是不确定的行为。

答案 2 :(得分:2)

在C ++中,下面的代码中的指针p和q有什么区别?
指针之间没有可见的区别,但是肯定有一个区别,这很重要。一个是指向整数的指针,另一个是指向整数的指针,它也是给定大小的数组中的第一个元素。

不幸的是,仅给出指针,您就无话可说。

如果我使用删除q会发生什么?
可能什么也不是,但是可能很多。

首先,调用delete而不是delete[]将在数组的第一个元素上调用析构函数一次,而不是在每个元素上调用析构函数。现在,像int这样的琐碎类型的析构函数什么也没做,所以...就目前而言,并没有真正的区别。但是,对于不是那么琐碎的类型,它们的析构函数(或析构函数链)实际上会做某事有很大的区别。

第二,您正在干扰基础原始内存块的正确释放。这可能(有时确实)导致严重崩溃。由于较早的损坏,它甚至可能导致崩溃,此崩溃随后会在不相关的无害代码段中发生。尝试调试。

或者,您可能会遇到无声的内存泄漏,这取决于实现,有时甚至取决于特定情况下的“运气”(例如是否达到页面边界)。
因为,分配和释放数组以及分配和释放单个元素完全不是一回事。它们(通常)的实现方式略有不同,尽管实现 可以应付不匹配的new / delete,但这并不能保证。与普通执行相比,在调试器中您可能会得到不同的行为。

调用错误的delete形式表示调用未定义的行为。这基本上意味着任何事情都可能发生。这包括“无”和“无法调试的问题”。它还包括编译器恶意优化的可能性,或者只是剥离了整个周围的功能,或者假定某个条件始终为真。这可能会导致非常令人讨厌的惊喜,您花了几天又几天的时间来弄清楚发生了什么。