我说的方式听起来有点奇怪,但那只是因为我不知道我怎么能说出来。我正在尝试实现A *,之前我做过但是我有一个问题跟踪我的路径,所以我决定进行一个小测试。问题是这样的:
我有一个看起来有点像这样的课程:
class Number {
public:
int xPos;
int yPos;
Number *prevNum;
Number(int x, int y) {
xPos = x;
yPos = y;
}
};
在主要功能中,我这样做
int main() {
Number n(2, 2);
Number *current = &n;
vector<Number> nums;
nums.push_back(*current);
for (unsigned i = 0; i < 15; i++) {
Number n(current->xPos + 1, current->yPos);
n.prevNum = current;
nums.push_back(n);
current = &n;
cout << current->xPos + 1 << " ";
}
for (unsigned i = 0; i < nums.size(); i++) {
if (nums.at(i).prevNum) {
cout << nums.at(i).prevNum->xPos << " ";
}
}
return 0;
}
出于某种原因,它会返回:
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 555437610 2 17 17 17 17 17 17 17 17 17 17 17 17 17 17
555437610每次都不同,所以我假设指针可能有错误。我可以无限地嵌套成员函数* prevNum吗?我不完全确定如何形容它。
答案 0 :(得分:3)
你的问题在于
current = &n;
在这里,您将获取循环局部变量的地址。在迭代结束时,变量被销毁,这意味着您有一个指向不再存在的对象的指针。取消引用该指针是未定义的行为。
如果要保持定义的行为,那么您应该做的是在向量中存储指向对象的指针。在调用push_back
之后,该指针可能会/将被无效,但由于您在此之前使用它,这将是正常的。
current = &nums.back();
您在存储前一个指针时也会遇到问题。如果从向量中捕获元素,如果向量重新分配空间,那么您将留下一个悬空指针。我认为您需要某种shared_ptr
设置才能使其正常运行。
答案 1 :(得分:2)
你有:
for (unsigned i = 0; i < 15; i++) {
Number n(current->xPos + 1, current->yPos);
n.prevNum = current;
nums.push_back(n);
current = &n;
cout << current->xPos + 1 << " ";
}
在那里,n
是一个局部变量,在循环结束时会被破坏。您正在存储指向局部变量的指针,稍后将使用它。
您的程序有不确定的行为。
我不清楚为什么需要prevNum
成员变量。
你可以完全摆脱它。
#include <iostream>
#include <vector>
using namespace std;
class Number {
public:
int xPos;
int yPos;
Number(int x, int y) {
xPos = x;
yPos = y;
}
};
int main() {
Number n(2, 2);
vector<Number> nums;
nums.push_back(n);
for (unsigned i = 0; i < 15; i++) {
Number n(2+i+1, 2);
nums.push_back(n);
cout << 2 + i+1 << " ";
}
cout << endl;
for (unsigned i = 0; i < nums.size(); i++) {
cout << nums.at(i).xPos << " ";
}
cout << endl;
return 0;
}
答案 2 :(得分:1)
n
的范围仅为for
循环。因此current = &n;
将current
设置为指向即将超出范围的对象。
nums.push_back(n);
将n
复制到矢量中,&nums.back()
分配给current
。
事实上,您的程序可以简化如下:
struct Number { // Now a proper aggregate
int xPos;
int yPos;
Number *prevNum;
};
vector<Number> nums {{1, 2, nullptr}};
nums.reserve(16);
for (unsigned i = 0; i < 15; ++i) {
Number& back = nums.back();
nums.emplace_back({back.xPos + 1, back.yPos + 1, &back});
cout << nums.back().xPos + 1 << " ";
}