c++ vector中的所有元素都指向同一个元素
All elements in a c++ vector point to the same element
我是一个完全的c++初学者,直到现在一切都很顺利。我对指针的概念很陌生(我来自python),我有这个奇怪的错误。
所以基本上,我创建了这个"SearchNode"类,并发现下面是它的方法之一"getChildren",它应该返回其他SearchNode实例的向量,表示骑士(棋盘)可以从当前状态移动到的可能单元格。(BFS)
也就是说,当我完成压入向量时,所有元素突然只指向第一个元素。有人能帮我一下吗?
PS:这是一个类似于c++的问题push_back没有't工作,因为它应该…但不像Angela(她在写自己的编译器),我完全是c++的初学者。非常感谢您的帮助。
去掉了int*,用数组表示状态。我现在可以成功地搜索图(因此状态是ok的)并找到最短路径,但我似乎无法重建路径。
为了测试,我从{0,0}开始,可以找到{4,4},但是根据getPath方法,路径是{4,4},{3,6},{3,6},{3,6}…({3,6}的无限循环)。是否有什么问题与我的父指针,或我的getPath函数?提前感谢您的支持。
//Search class
class SearchNode
{
public:
//Variables
SearchNode *m_parent;
array<int,2> m_state; //I don't understand typedef's yet, will use them when I'm clearer with them :)
//Normal Constructor
SearchNode(array<int,2>& state_, SearchNode *parent_=nullptr) :
m_state(state_),
m_parent(parent_)
{}
//Method to get Next reachable states. Returns instances of SearchNode.
vector<SearchNode> getChildren()
{
int legalMoves[8][2] = {{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
vector<SearchNode> children;
children.reserve(8);
for(int i=0; i<8; i++)
{
int x = (m_state[0] + legalMoves[i][0]);
int y = (m_state[1] + legalMoves[i][1]);
if( (x>-1) and (x<9) and (y<9) and (y>-1)) // Within the bounds of the board
{
array<int,2> childState = {x,y};
SearchNode childNode = SearchNode(childState,this);
children.push_back(childNode);
}
}
return children;
}
void getPath()
{
cout<<"nPath: ";
cout<< this->print();
SearchNode current = *this;
unsigned int counter = 1;
while((current.m_parent!=nullptr) and counter< 10)
{
counter++;
cout<< (current.m_parent)->print();
current = *(current.m_parent);
}
cout << (current.m_parent)->print();
}
string print()
{
stringstream out;
out << "{" << this->m_state[0] << "," << this->m_state[1] << "} ";
return out.str();
}
};
有很多错误和错误,我强烈建议您在编译器中打开警告级别,以便您可以获得更多信息。在GCC/g++/Clang中,尝试使用"-Wall"或"-Wextra",正如moshbear指出的那样。
你的节点永远不会被分配"父"值,你正在创建一个名为"父"的"影子"局部变量并分配它。为避免此类常见错误,请为成员变量名使用前缀或后缀,以将其与本地名称分开。"m_parent"或"_parent".
不要在构造函数中赋值,要显式地不初始化这些值。
SearchNode()
{
//do nothing
}
然后在基于指针的构造函数中引入这些垃圾数据,你可能想要的是
SearchNode() : parent(NULL), state(NULL) {}
你的复制构造函数是一个灾难。你需要仔细阅读并理解指针和局部变量。
//Start Node constructor. Still looking for an equivalent for null.
SearchNode(int *state)
{
int genericStartState[2] = {-1,-1};
SearchNode blankParent = SearchNode();
SearchNode genericStart = SearchNode(genericStartState,&blankParent);
this->parent = &genericStart;
this->state=state;
}
首先,这里的"blankParent"是一个包含随机数据的局部变量,因为当前的复制构造函数。其次,你取的是它的地址——一个私有的局部变量的地址,当你在例程末尾按下"}"时,它即将停止存在。
"genericStartState"也即将超出作用域。
除此之外,我不认为你想要或需要这个特殊的构造函数。
但从根本上说,你的主题中的错误,是因为你在你的赋值循环中做了同样的事情——你使用一个临时的,局部数组来存储新的值,然后传递一个指针到你的构造函数。因为你取的是地址,所以每次循环都是相同的。
int childState[2] = { x, y };
SearchNode childNode = SearchNode(childState,this);
这就是为什么你所有的节点都有相同的状态——因为它们都指向相同的内存位置(编辑:正如DyP指出的那样,这种副作用不是你可以指望的,在这种情况下只是排序的产物)。
在节点结构中使用简单的整型数组可能比使用指针更容易。
如果你的编译器是VisualStudio 2012或g++ 4.8或Clang 4.2,那么下面是构造函数的样子。
class SearchNode
{
public:
typedef std::array<int, 2> State;
private:
// I use the 'm_' convention for members, 'g_' for globals, 's_' for statics.
SearchNode* m_parent;
State m_state;
public:
//////////
// Default ctor.
SearchNode()
: m_parent(nullptr) // C++11 constant meaning pointer with value 0
, m_state({-1, -1}) // preferred but requires recent C++11 features
{
//m_state[0] = m_state[1] = -1; // had to do this instead for gcc 4.7.3
}
//////////
// Normal ctor
// I use the '_'-postfix convention for parameter names.
SearchNode(SearchNode* parent_, const State& state_)
: m_parent(parent_)
, m_state(state_)
{
}
//////////
// Copy constructor.
// We could do this, but it's the default behavior anyway.
/*
SearchNode(const SearchNode& rhs)
: m_parent(rhs.m_parent)
, m_state(rhs.m_state)
{
}
*/
// Current C++11 compilers let us be explicit and do this:
//SearchNode(const SearchNode& rhs) = default;
// But it's the default behavior so we don't have to do this one at all.
};
最新的c++ 11语言变化(MSVC> 2012, GCC>= 4.8, Clang>= 4.1)将允许您用
替换前两个构造函数。// Kill two birds with one stone and have default parameters on our normal ctor,
// replacing both the default and normal ctor with one function.
SearchNode(SearchNode* parent_ = nullptr, const State& state_ = { -1, -1 }))
: m_parent(parent_)
, m_state(state_)
{
}
如果你有一个完全兼容c++的编译器,你可以把这一切归结为:
class SearchNode
{
public:
typedef std::array<int, 2> State;
private:
// I use the 'm_' convention for members, 'g_' for globals, 's_' for statics.
SearchNode* m_parent = nullptr; // c++1y keyword to replace 'NULL'
State m_state = { -1, -1 };
public:
SearchNode() = default;
SearchNode(const State& rhs_) = default; // not strictly required.
SearchNode(SearchNode* parent_, const State& state_)
: m_parent(parent_), m_state(state_)
{}
};
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 使用函数"remove"删除重复元素
- 具有最大子序列大小的序列,每个元素都相同
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 如何将元素添加到数组的线程安全函数?
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 我想访问std::unique_ptr中的一个特定元素
- 如何通过 getter 函数删除矢量的元素?
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- c++ vector中的所有元素都指向同一个元素
- 所有元素都指向同一个对象