C++ 什么是;(新型[n])和#x2B;1“;返回?

C++ 什么是;(新型[n])和#x2B;1“;返回?,c++,pointers,pointer-arithmetic,C++,Pointers,Pointer Arithmetic,通过引用,可以说new操作符返回指向分配的新内存块开始的指针。让我们再次假设,任何指针都具有指针算法的特性,如果p是指针,则可以使p+1指向内存中的下一个位置。 基于上述假设,我尝试了以下步骤 #include <iostream> using namespace std; int main(){ int * ptr = (new int [4]) + 1; ptr[3] = 2; cout << ptr[3] << endl;

通过引用,可以说
new
操作符返回指向分配的新内存块开始的指针。让我们再次假设,任何指针都具有指针算法的特性,如果
p
是指针,则可以使
p+1
指向内存中的下一个位置。 基于上述假设,我尝试了以下步骤

#include <iostream>
using namespace std;
int main(){
    int * ptr = (new int [4]) + 1;
    ptr[3] = 2;
    cout << ptr[3] << endl;
    /*Before delete the dynamic allocated memory, 
      it should be necessary to let ptr point to the 
      beginning of it, add one line to do that:
      --ptr;*/
    delete [] ptr;
}
#包括
使用名称空间std;
int main(){
int*ptr=(新int[4])+1;
ptr[3]=2;
库特
将指向
ptr[0]
,因此

int * ptr = (new int [4]) + 1;

将跳转到
ptr[1]
,您将无法释放
ptr
,除非您执行类似
delete(ptr--)

超出边界是未定义的行为

当使用不同的编译器、不同的编译标志编译时,甚至在不同的时间运行时,您可能会得到不同的结果。您的计算机可能会关机,显示器可能会烧坏


返回正确的值也是未定义的行为之一。

C/C++允许您向越界内存分配/读取值,因为这是未定义的行为

例如,这是有效的代码:

int *array = new int[10];
array[10] = 5;
std::cout<<array[10];
int*array=newint[10];
数组[10]=5;
标准::cout
我希望
ptr[3]
应该超出新分配的内存范围

确实如此。您需要小心不要这样做,因为(正如您所注意到的)这是一个通常无法检测到的错误。像这样的动态分析工具可以帮助诊断这些问题,但并不完美

然而,结果仍然是2

这意味着在数组末尾之外碰巧有可访问的内存,因此无法检测到无效的访问。相反,它重写了不属于数组的内存—可能是未使用的内存,也可能是您覆盖了一些其他数据,这将在以后导致令人困惑的错误

为什么指针算术变得无用

它和任何指针算法一样有用。指针算法无法检测数组的结尾,因此如果超出范围,就会出现未定义的行为

或者它真的是
新类型
返回
*类型
的对象吗

new Type[]
返回一个指向已分配数组的
Type*
指针。它的行为与任何其他指针一样,因此添加一个指针将为您提供指向第二个元素的指针


delete[]ptr
也给出了未定义的行为,因为
ptr
不再指向分配数组的开始。

访问数组边界以外的元素是未定义的行为。程序可能不会立即崩溃,或者根本不会崩溃。但仍然会造成损坏。它返回一个指向分配数组的第二个元素的指针,并返回c导致内存泄漏。但是,它没有发生。为什么?尽管我认为让访问元素超出数组边界是愚蠢的。因为在这种情况下,内存存在并且可以访问,而您将2放入其中。如果不可访问,则分配将失败,而不是后续读取。您的期望有点奇怪。@Life:它是2,因为这是你在那里写的,在你读回它之前,没有其他东西会改变它。内存不会因为你以一种不可靠的方式访问它而停止像内存一样的行为。不,它不会。它允许你使用一个指针值,但取消引用它是未定义的行为。你的编辑是允许的还是取消罚款行为。你不能两全其美-1@EJP我只说你可以“分配”,现在还编辑了“阅读”部分。我没有说任何关于取消引用的内容。这是一个没有区别的区别。如果不取消引用指向越界内存的指针,您就无法读取或分配越界内存,如您的示例中所示。“as”部分甚至没有意义。我不明白谁会指向ptr[1]?是ptr本身吗?谢谢,@SaniHuttunen,你说得对。总之,这不是一个好的做法。@Life。我没有清楚地解释自己。我想说的是,做
int*ptr=(new int[4])+1;
,ptr将指向
new int[4]分配的下一个地址(增加
sizeof(int)
是的,我想是的。但是有什么方法可以测试这个想法吗?你已经测试过了,你很幸运。不要依赖它,也不要认为它是你应该测试的。谢谢。你的答案太棒了。
int *array = new int[10];
array[10] = 5;
std::cout<<array[10];