在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
会怎样?
答案 0 :(得分:18)
指针本身是完全无法区分的。这就是为什么您必须记住匹配new
/ delete
和new[]
/ delete[]
的原因。
不匹配它们会触发不确定的行为。
答案 1 :(得分:4)
使用new []
时,某些c++
实现会在指针返回之前跟踪地址中数组的分配大小。这是标准未定义的实现细节。
以下答案更详细地描述了这种可能的实现:How could pairing new[] with delete possibly lead to memory leak only?
您必须始终将new
与delete
和new []
与delete []
进行匹配。混合这些是不确定的行为。
答案 2 :(得分:2)
在C ++中,下面的代码中的指针p和q有什么区别?
指针之间没有可见的区别,但是肯定有一个区别,这很重要。一个是指向整数的指针,另一个是指向整数的指针,它也是给定大小的数组中的第一个元素。
不幸的是,仅给出指针,您就无话可说。
如果我使用删除q会发生什么?
可能什么也不是,但是可能很多。
首先,调用delete
而不是delete[]
将在数组的第一个元素上调用析构函数一次,而不是在每个元素上调用析构函数。现在,像int
这样的琐碎类型的析构函数什么也没做,所以...就目前而言,并没有真正的区别。但是,对于不是那么琐碎的类型,它们的析构函数(或析构函数链)实际上会做某事有很大的区别。
第二,您正在干扰基础原始内存块的正确释放。这可能(有时确实)导致严重崩溃。由于较早的损坏,它甚至可能导致崩溃,此崩溃随后会在不相关的无害代码段中发生。尝试调试。
或者,您可能会遇到无声的内存泄漏,这取决于实现,有时甚至取决于特定情况下的“运气”(例如是否达到页面边界)。
因为,分配和释放数组以及分配和释放单个元素完全不是一回事。它们(通常)的实现方式略有不同,尽管实现 可以应付不匹配的new
/ delete
,但这并不能保证。与普通执行相比,在调试器中您可能会得到不同的行为。
调用错误的delete
形式表示调用未定义的行为。这基本上意味着任何事情都可能发生。这包括“无”和“无法调试的问题”。它还包括编译器恶意优化的可能性,或者只是剥离了整个周围的功能,或者假定某个条件始终为真。这可能会导致非常令人讨厌的惊喜,您花了几天又几天的时间来弄清楚发生了什么。