为什么 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
而不是一个, 顺便说一下,这将使您的其余代码有效,除了您没有 delete
由 new
分配的内存,这将导致内存泄漏。
现在考虑以下代码:
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 其中提到:没有对程序行为的限制.
据我了解
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
而不是一个, 顺便说一下,这将使您的其余代码有效,除了您没有 delete
由 new
分配的内存,这将导致内存泄漏。
现在考虑以下代码:
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 其中提到:没有对程序行为的限制.