写完下面的代码后:
#include <iostream>
using namespace std;
typedef struct Node {
int value;
Node(int index) {
value = index;
}
} Node;
int main() {
Node* arr[10];
for(int i = 0; i < 10; i++) {
arr[i] = &Node(i);
}
for(int i = 0; i < 10; i++)
cout << arr[i]->value << endl;
}
Run Code Online (Sandbox Code Playgroud)
我看到代码只打印了9个,而不是从0到9的所有数字.在调试代码后,我看到每个i的arr [i]的地址是相同的,并且Node(i)只为arr [i]释放了一次空间,之后唯一value = index
没有释放任何其他空间的东西.为什么?
这一行:arr[i] = &Node(i);
存储指向临时对象的指针.Node(i)
创建一个临时对象,该对象可以在语句的末尾被破坏,此时对它的所有引用都变为无效,这意味着任何解引用代码的结果arr[i]
都是未定义的.在这种情况下你获得全部9的原因是因为编译器正在优化代码 - 因为一次只Node(i)
创建一个临时代码,编译器只是在每次循环时重用该内存.
要解决这个问题,请为每个对象分配堆内存:arr[i] = new Node(i);
.然后,当您完成使用它们时,您还需要记住删除每个:
for (int i=0; i < 10; ++i) {
delete arr[i];
}
Run Code Online (Sandbox Code Playgroud)
如果你想进一步研究,可以尝试在你的Node
类中添加一些代码来查看发生了什么:例如打印出this
构造函数中的地址,和/或创建一个只打印消息的析构函数,这样你就可以看到它被调用了.