vector中push_back一个带指针的对象后指针指向的值发生改变,以下是例子,这是什么原因,请大侠能帮忙

Ariel_jl 2014-10-29 08:59:22
// 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;
}
...全文
730 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
Ariel_jl 2014-10-31
  • 打赏
  • 举报
回复
膜拜,受教了,讲的透彻,谢谢
Ariel_jl 2014-10-30
  • 打赏
  • 举报
回复
你好,这里的情况好像跟那边不太一样,书上讲的是指向容器元素的指针,我这是元素里面的指针,minVec里面初始为空,添加进去一个元素后按理元素里面的指针指向内容不会变的,而迭代器it在push到minVec时,open也还没执行erase操作的,it 跟minVec[0]的parent指向内容怎么就变了,如果我还是用vector的话 可不可以给我一些改进的建议,谢谢了!
passion_wu128 2014-10-30
  • 打赏
  • 举报
回复
第一次调用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;
}
「已注销」 2014-10-29
  • 打赏
  • 举报
回复
见 《c++ primer》315页   向容器中添加和删除元素的操作可能是指向容器的迭代起,指针,引用失效
一个失效的指针,引用,迭代器将不在表示任何元素。

65,204

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧