为什么new int()在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

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

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


据我理解

int* p = new int();

类似于用构造函数创建int

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

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

现在考虑下面的代码:

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

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

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

需要注意的一件重要的事情是,在某些情况下,其他语言可能会阻止你涉足其中,但c++不会,它相信程序员会写出正确的代码,这就是为什么当一个c++程序员通常比较困难的原因。


正如已经指出的,您的程序在访问p[1]时发生未定义行为。注意链接资源的第一个短语,它简单地声明:

[未定义行为]如果违反了语言的某些规则,则使整个程序无意义

这就是这里的情况,您正在访问的内存位于手动内存分配所定义的边界之外。事实上,输出是你所期望的是一个(坏的,我会说)运气的问题,它可能今天输出正确的结果,明天崩溃,谁知道呢。

从上面的例子可以看出,这种情况很难诊断,对于3个例子来说,它是完全相同的类型。

在任何情况下,都有像这样诊断内存问题的方法,例如valgrind和gcc地址消毒器等。


附带说明,避免使用原始指针,如果可能,使用智能指针或c++容器之一。

我还鼓励您获得一些有关OOP RAII原则的相关主题的知识。

为什么下面的代码像数组一样工作?

它不。程序有未定义行为意思是它仍然是错误的,即使它没有这么明确地说,而且"似乎在工作"。这是由于在你的程序中使用了表达式p[1]p[i]

未定义行为意味着任何1都可能发生,包括但不限于给出预期输出的程序。但是从不依赖(或基于)具有未定义行为的程序的输出。程序可能会崩溃。

所以你看到的输出(可能看到的)是未定义行为的结果。正如我所说的不要依赖于输出一个有UB的项目程序可能会崩溃。

因此,使程序正确的第一步是删除UB。当且仅当你可以开始对程序的输出进行推理。


1对于未定义行为的更准确的技术定义,请参见这里提到的:对程序的行为没有限制

最新更新