为什么 new int() 像 C++ 中的数组一样工作?

Why does new int() work like an array in C++?

据我了解

int* p = new int();

有点像用构造函数创建一个int。如果是这样,为什么下面的代码像数组一样工作?

int* p = new int();
    
*p = 5;
    
p[1] = 15;
    
for (int i = 0; i < 2; i++)
    cout << p[i] << endl;
5
15

Why does new int() work like an array in C++?

p[1]等同于*(p + 1),它只是解引用指针来访问存储在它指向的内存位置的值,表示法类似于数组表示法,它是允许的并且是优于指针表示法,因为它更具可读性。


As far as I understand

 int* p = new int();

Is something like creating an int with a constructor.

是的,但这还不是全部,您还恰好为一个int分配内存并将内存地址分配给指针p

请注意,它可能是 int* p = new int[2],它是完全相同的指针,但在这种情况下,new 返回的内存块适用于 2 个 int 而不是一个, 顺便说一下,这将使您的其余代码有效,除了您没有 deletenew 分配的内存,这将导致内存泄漏。

现在考虑以下代码:

int arr[10];
int* p = arr;

在这种情况下,您有完全相同的指针,但它将指向具有自动存储持续时间的数组的第一个元素。

指针不知道它指向多少内存,因为它指向给定内存块中的第一个元素,对于程序来说,该块有多大并不明显。索引指针时,程序员有责任不超出该内存。

需要注意的一件重要事情是,在某些情况下,其他语言可能会阻止您涉足其中,而 C++ 不会,它相信程序员会生成正确的代码,这就是为什么它通常更难成为C++ 程序员。


正如已经指出的,您的程序在访问 p[1] 时发生在 undefined behavior 中。请注意链接资源的第一个短语,它只是说明:

[Undefined behavior] renders the entire program meaningless if certain rules of the language are violated

就是这种情况,您正在访问的内存超出了您手动分配内存所定义的范围。输出是你期望的事实是(坏,我会说)运气的问题,它可能今天输出正确的结果明天就崩溃了,谁知道呢。

从上面的例子可以看出,这种情况很难诊断,3个样本完全是同一类型。

无论如何,有一些方法可以像这样诊断内存问题,例如valgrind and gcc address sanitizer等。


附带说明,避免使用原始指针,尽可能使用 smart pointers or one of the C++ containers

我还鼓励您获得一些关于 OOP RAII principles 的相关主题的知识。

why does the following code work like an array?

没有。该程序有未定义的行为,这意味着它仍然存在错误,即使它没有明确说明并且“似乎正在运行”。这是由于在您的程序中使用了表达式 p[1]p[i]

Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.

所以您看到(也许看到)的输出是未定义行为的结果。正如我所说,不要依赖具有 UB 的程序的输出。程序可能会崩溃。

因此,使程序正确的第一步是删除 UB。 然后并且只有那时你可以开始对程序的输出进行推理。


1有关未定义行为的技术上更准确的定义,请参阅 this 其中提到:没有对程序行为的限制.