vector中push_back一个带指针的对象后指针指向的值发作改变,以下是例子,这是什么原因,请大侠能帮忙
vector中push_back一个带指针的对象后指针指向的值发生改变,以下是例子,这是什么原因,请大侠能帮忙
// pushback.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include<vector>
using namespace std;
struct Node
{
int value;
Node *parent;
Node(int val):value(val)
{
parent=NULL;
}
Node(const Node&nd)
{
value=nd.value;
parent=nd.parent;
}
void print()
{
cout<<"value:"<<value<<endl;
}
};
vector<Node> open;
vector<Node> minVec;
void getMinFromOpen(vector<Node> &minVec) //可以排序优化
{
int f=0;
minVec.clear();
vector<Node>::iterator it = open.begin();
int fMin =10;
for ( ; it != open.end(); it++)
{
f =it->value;
if (f < fMin)
fMin = f;
}
for (it = open.begin(); it != open.end(); )
{
f=it->value ;
if (f == fMin)
{//push_back Adds a new element at the end of the vector, after its current last element. The content of this new element is initialized to a copy of x
if(it->parent)
it->parent->print();
minVec.push_back(*it); //有问题
if(it->parent)
it->parent->print();
it = open.erase(it);
continue;
}
it++;
}
}
void step( Node &cur,vector<Node> &subNode)
{
Node n1(cur);
n1.value=cur.value+8;
n1.parent=&cur;
subNode.push_back(n1);
Node n2(cur);
n2.value=cur.value+2;
n2.parent=&cur;
subNode.push_back(n2);
Node n3(cur);
n3.value=cur.value+5;
n3.parent=&cur;
subNode.push_back(n3);
}
int _tmain(int argc, _TCHAR* argv[])
{
Node n1(1);
open.push_back(n1);
vector<Node> minVec;
vector<Node> subNodes;
getMinFromOpen(minVec);
step(minVec[0],subNodes);
for(vector<Node>::iterator is = subNodes.begin(); is != subNodes.end(); is++)
{
open.push_back(*is);
}
getMinFromOpen(minVec);
return 0;
}
------解决思路----------------------
------解决思路----------------------
第一次调用getMinFromOpen的时候没什么问题,这里只讨论之后的。
step(minVec[0],subNodes);
这行代码表示把minVec[0]用作subNodes的parent.
而在之后的getMinFromOpen中调用了minVec.clear();subNode的parent被析构,minVec的size变为0,但之前为添加一个元素分配的内存依然存在,实际上此时minVec的capacity为1,下一次再push_back一个元素的时候将会使用此地址。
所以你push_back第一个元素的时候,它将取代之前的minVec[0],它的parent实际上指向了自身,这样就会变化。
如果之后再push_back一个元素,capacity将不够用,内存从新分配,之前的内存将会被析构。it的parent更会乱掉。
所以不要让node的parent指向一个可能会变的地址。
最好的做法是vector里面放Node的指针,自己决定何时delete。
针对的你程序最小的改动是让subNode的parent指向栈上的对象,main函数退出前不会被析构。
还有个建议是尽量用stl算法,不要重复地造轮子。
最后一个建议,给别人看代码的时候尽量用代码格式,你看你发的贴代码多乱。
下面是按照你的逻辑大致修改的程序:
// pushback.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include<vector>
using namespace std;
struct Node
{
int value;
Node *parent;
Node(int val):value(val)
{
parent=NULL;
}
Node(const Node&nd)
{
value=nd.value;
parent=nd.parent;
}
void print()
{
cout<<"value:"<<value<<endl;
}
};
vector<Node> open;
vector<Node> minVec;
void getMinFromOpen(vector<Node> &minVec) //可以排序优化
{
int f=0;
minVec.clear();
vector<Node>::iterator it = open.begin();
int fMin =10;
for ( ; it != open.end(); it++)
{
f =it->value;
if (f < fMin)
fMin = f;
}
for (it = open.begin(); it != open.end(); )
{
f=it->value ;
if (f == fMin)
{//push_back Adds a new element at the end of the vector, after its current last element. The content of this new element is initialized to a copy of x
if(it->parent)
it->parent->print();
minVec.push_back(*it); //有问题
if(it->parent)
it->parent->print();
it = open.erase(it);
continue;
}
it++;
}
}
void step( Node &cur,vector<Node> &subNode)
{
Node n1(cur);
n1.value=cur.value+8;
n1.parent=&cur;
subNode.push_back(n1);
Node n2(cur);
n2.value=cur.value+2;
n2.parent=&cur;
subNode.push_back(n2);
Node n3(cur);
n3.value=cur.value+5;
n3.parent=&cur;
subNode.push_back(n3);
}
int _tmain(int argc, _TCHAR* argv[])
{
Node n1(1);
open.push_back(n1);
vector<Node> minVec;
vector<Node> subNodes;
getMinFromOpen(minVec);
step(minVec[0],subNodes);
for(vector<Node>::iterator is = subNodes.begin(); is != subNodes.end(); is++)
{
open.push_back(*is);
}
getMinFromOpen(minVec);
return 0;
}
------解决思路----------------------
见 《c++ primer》315页 向容器中添加和删除元素的操作可能是指向容器的迭代起,指针,引用失效
一个失效的指针,引用,迭代器将不在表示任何元素。
------解决思路----------------------
第一次调用getMinFromOpen的时候没什么问题,这里只讨论之后的。
step(minVec[0],subNodes);
这行代码表示把minVec[0]用作subNodes的parent.
而在之后的getMinFromOpen中调用了minVec.clear();subNode的parent被析构,minVec的size变为0,但之前为添加一个元素分配的内存依然存在,实际上此时minVec的capacity为1,下一次再push_back一个元素的时候将会使用此地址。
所以你push_back第一个元素的时候,它将取代之前的minVec[0],它的parent实际上指向了自身,这样就会变化。
如果之后再push_back一个元素,capacity将不够用,内存从新分配,之前的内存将会被析构。it的parent更会乱掉。
所以不要让node的parent指向一个可能会变的地址。
最好的做法是vector里面放Node的指针,自己决定何时delete。
针对的你程序最小的改动是让subNode的parent指向栈上的对象,main函数退出前不会被析构。
还有个建议是尽量用stl算法,不要重复地造轮子。
最后一个建议,给别人看代码的时候尽量用代码格式,你看你发的贴代码多乱。
下面是按照你的逻辑大致修改的程序:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct Node
{
int value;
Node *parent;
Node(int val)
:value(val), parent(NULL)
{
}
Node(const Node& nd)
{
value = nd.value;
parent = nd.parent;
}
bool operator<(const Node& node)
{
return value < node.value;
}
bool operator==(const Node& node)
{
return value == node.value;
}
void print()
{
cout<<"value:"<<value<<endl;
}
};
static vector<Node> openVec;
void getMinFromOpen(vector<Node> &minVec) //可以排序优化
{
minVec.clear();
Node minNode = *min_element(openVec.begin(), openVec.end());
vector<Node>::iterator it = find(openVec.begin(), openVec.end(), minNode);
while(it != openVec.end())
{
if(it->parent)
{
it->parent->print();
}
minVec.push_back(*it);
openVec.erase(it);
it = find(openVec.begin(), openVec.end(), minNode);
}
}
void step( Node &cur,vector<Node> &subNode)
{
int valueOffset[] = {8, 2, 5};
for(size_t i = 0; i < sizeof(valueOffset) / sizeof(valueOffset[0]); i++)
{
Node node(cur.value + valueOffset[i]);
node.parent = &cur;
subNode.push_back(node);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Node n1(1);
openVec.push_back(n1);
vector<Node> minVec;
vector<Node> subNodes;
getMinFromOpen(minVec);
Node node = minVec[0]; //node对象在main结束时才会被析构
step(node,subNodes);
for(vector<Node>::iterator is = subNodes.begin(); is != subNodes.end(); is++)
{
openVec.push_back(*is);
}
getMinFromOpen(minVec);
return 0;
}