atoms[0].resid :0x96fc250 &(atoms[0].resid->ID) :0x96fc25c **(atoms[0].resid->ID) :1** atoms[1].resid :0x96fc250 &(atoms[1].resid->ID) :0x96fc25c **(atoms[1].resid->ID) :1** atoms[2].resid :0x96fc3ec &(atoms[2].resid->ID) :0x96fc3f8 (atoms[2].resid->ID) :2 atoms[3].resid :0x96fc3ec &(atoms[3].resid->ID) :0x96fc3f8 (atoms[3].resid->ID) :2 --------------------------------------- atoms[0].resid :0x96fc250 &(atoms[0].resid->ID) :0x96fc25c **(atoms[0].resid->ID) :891301941** atoms[1].resid :0x96fc250 &(atoms[1].resid->ID) :0x96fc25c **(atoms[1].resid->ID) :891301941** atoms[2].resid :0x96fc3ec &(atoms[2].resid->ID) :0x96fc3f8 (atoms[2].resid->ID) :2 atoms[3].resid :0x96fc3ec &(atoms[3].resid->ID) :0x96fc3f8 (atoms[3].resid->ID) :2
这是代码。我真的不知道我做错了什么
#define FT_GRO 1
using namespace std;
class residue{
public:
residue(){}
residue(const residue& r){atoms=r.atoms; ID=r.ID; name= r.name;}
residue(int n, string s) {name=s;ID=n;}
public:
vector<class atom*> atoms;
int ID;
string name;
atom& addAtom(atom& a) { atoms.push_back(&a); return a;}
};
class atom{
public:
atom(){}
atom(const atom& a){ID=a.ID,name=a.name,coord=a.coord,resid=a.resid ;}
atom(const int anum, const string aname, const point3D& p, residue& res){coord=p; name=aname; resid=&res; ID=anum;}
~atom(){}
public:
point3D coord;
int ID;
string name;
double distance(point3D& p) {return coord.distance(p);}
double distance(atom& p) {return coord.distance(p.coord);}
class residue* resid;
};
int main(){
vector<atom> atoms;
vector<residue> residues;
double box1,box2,box3,x,y,z;
char l[256];
int nr,na;
string sr,sa;
int lastResNum = -1;
string lastResName("");
int nAtomsIn=4;
for(int i =0; i<nAtomsIn;i++){
cin.getline(l,255);
istringstream ssatm(l,ios::in);
ssatm >> setw(5) >> nr >> setw(5) >> sr >> setw(5) >> sa >> setw(5) >>na >> setw(8) >> x >>setw(8) >> y >>setw(8) >> z;
if (lastResNum!=nr || sr!=lastResName){
residues.push_back(residue(nr,sr));
}
point3D p(x,y,z);
atoms.push_back( atom(na,sa,p,residues.back()) );
residues.back().addAtom(atoms.back());
cout << "atoms["<<i<<"].resid :" << atoms[i].resid << endl;
cout << "&(atoms["<<i<<"].resid->ID) :" << &(atoms[i].resid->ID) << endl;
cout << "&(atoms["<<i<<"].resid->ID) :" << (atoms[i].resid->ID) << endl;
lastResNum=nr; lastResName=sr;
}
cout << "---------------------------------------"<<endl;
cin.getline(l,255);
istringstream ssbox(l);
ssbox >> setw(10) >> box1>>setw(10) >> box2>>setw(10) >> box3;
for(int i =0; i<atoms.size();i++){
cout << "atoms["<<i<<"].resid :" << atoms[i].resid << endl;
cout << "&(atoms["<<i<<"].resid->ID) :" << &(atoms[i].resid->ID) << endl;
cout << "&(atoms["<<i<<"].resid->ID) :" << (atoms[i].resid->ID) << endl;
}
return 0;
}
答案 0 :(得分:13)
您所看到的是完全正常的行为 - 当您向向量添加新元素时,它可能会被调整大小,因此所有元素都会被复制到新的内存位置。
如果您需要保证现有元素不会在内存中移动,请使用其他容器,例如list
或set
。
答案 1 :(得分:1)
std :: vector会在需要更多空间时移动内存。它分配一个连续的内存块,当该块填满时,它会分配一个更大的块,将旧块中的所有元素复制到新块,释放旧块,然后继续。
为了防止您看到的行为,您可以执行以下任何操作来改善设计模式:
1)在main()中更改向量以存储指针而不是堆栈选项。这样,对象将始终位于内存中的相同位置。 2)通过实现复制构造函数和赋值运算符来更改类声明以允许深层复制 3)修改类heirarchy以消除类之间的循环依赖关系。你可以通过一个Residue类,一个Atom类和另一个将2映射到彼此的类来实现这一点。
最简单的选项是#1。你只需要确保正确清理内存。
答案 2 :(得分:0)
就像卡萨布兰卡所说,每当你的矢量扩展时,它就会改变物体在记忆中的位置。 如果你真的想使用向量而不是其他容器
1)你可以为你的矢量reserve
一大块内存。如果您保证这些对象的数量不会超过某个范围,并且您不介意消耗那么多内存,那么请将您的向量设置为大。
2)使它们成为指针的向量。如果你有一个非常现代的编译器(例如gcc&gt; = 4.4),你甚至可以从C ++ 0x访问新的unique_ptr智能指针类,它允许你在stl容器中使用智能指针。这些对语言的重要补充。