Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 两个函数调用之间的内存更改_C++ - Fatal编程技术网

C++ 两个函数调用之间的内存更改

C++ 两个函数调用之间的内存更改,c++,C++,这完全奇怪。我有一些代码,从文件中读取一些参数,并将它们存储在两个stl向量中。我有原子和残基,每个原子都有一个指向残基的指针。一旦完成读取,在声明变量后,内存中的值似乎已更改: 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].re

这完全奇怪。我有一些代码,从文件中读取一些参数,并将它们存储在两个stl向量中。我有原子和残基,每个原子都有一个指向残基的指针。一旦完成读取,在声明变量后,内存中的值似乎已更改:

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 原子[0]。剩余:0x96fc250 &(原子[0]。剩余->ID):0x96fc25c **(原子[0]。剩余->ID):1** 原子[1]。剩余:0x96fc250 &(原子[1]。剩余->ID):0x96fc25c **(原子[1]。剩余->ID):1** 原子[2]。剩余物:0x96fc3ec &(原子[2]。剩余->ID):0x96fc3f8 (原子[2]。剩余->ID):2 原子[3]。剩余物:0x96fc3ec &(原子[3]。剩余->ID):0x96fc3f8 (原子[3]。剩余->ID):2 --------------------------------------- 原子[0]。剩余:0x96fc250 &(原子[0]。剩余->ID):0x96fc25c **(原子[0].剩余->ID):891301941** 原子[1]。剩余:0x96fc250 &(原子[1]。剩余->ID):0x96fc25c **(原子[1].剩余->ID):891301941** 原子[2]。剩余物:0x96fc3ec &(原子[2]。剩余->ID):0x96fc3f8 (原子[2]。剩余->ID):2 原子[3]。剩余物:0x96fc3ec &(原子[3]。剩余->ID):0x96fc3f8 (原子[3]。剩余->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;

}
#定义FT\u GRO 1
使用名称空间std;
类剩余{
公众:
剩余(){}
剩余(常量剩余&r){atoms=r.atoms;ID=r.ID;name=r.name;}
剩余(int n,字符串s){name=s;ID=n;}
公众:
矢量原子;
int-ID;
字符串名;
atom&addAtom(atom&a){atoms.push_back(&a);return a;}
};
类原子{
公众:
原子(){}
atom(const atom&a){ID=a.ID,name=a.name,coord=a.coord,resid=a.resid;}
atom(常量int anum、常量字符串aname、常量point3D&p、residence&res){coord=p;name=aname;resid=&res;ID=anum;}
~atom(){}
公众:
point3D坐标;
int-ID;
字符串名;
双距离(点3d&p){返回坐标距离(p);}
双距离(原子&p){返回坐标距离(p坐标);}
类别剩余*剩余;
};
int main(){
矢量原子;
载体残基;
双盒子1,盒子2,盒子3,x,y,z;
charl[256];
国际注册号,不适用;
串sr,sa;
int lastResNum=-1;
字符串lastResName(“”);
int-nAtomsIn=4;
对于(inti=0;i>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){
残留物。推回(残留物(nr,sr));
}
点3dp(x,y,z);
原子。推回(原子(na,sa,p,残留物。back());
残留物.back().addAtom(atoms.back());

cout您看到的是完全正常的行为——当您向向量添加新元素时,它可能会调整大小,因此所有元素都会复制到新的内存位置


如果您需要保证现有元素不会在内存中移动,请使用不同的容器,如
list
set

std::vector将在需要更多空间时移动内存。它分配一个连续的内存块,当该块填满时,它将分配一个更大的块,从旧的b锁定到新块,释放旧块,然后继续

为了防止您看到的行为,您可以执行以下任一操作来改进您的设计模式:

1) 将main()中的向量更改为存储指针而不是堆栈选项。这样,对象将始终位于内存中的同一位置。 2) 通过实现复制构造函数和赋值运算符,更改类声明以允许深度复制 3) 修改类继承权以删除类之间的循环依赖关系。可以通过使用剩余类、Atom类和另一个将2映射到彼此的类来完成此操作


最简单的选择是#1。你只需要确保正确清理内存。

就像卡萨布兰卡所说的,每当向量展开时,它就会改变对象在内存中的位置。 如果你真的想用向量来代替其他的容器

1) 您可以
为向量保留一大块内存。如果您保证这些对象的数量不会超过某个界限,并且您不介意使用那么多内存,那么请将向量设置为这么大


2) 如果你有一个非常现代的编译器(例如gcc>=4.4),就把它们变成指针的向量,您甚至可以从C++0x访问新的unique_ptr智能指针类,该类允许您在stl容器中使用智能指针。这些对语言的伟大添加。

对,在向容器添加新元素时,使用
list
而不是
vector
来防止复制。@chrisayock:我只是想添加它。:)或m确保向量不会移动它们。如果确保向量不会溢出其当前区域(通过预调整大小,例如reserve()),则不会移动对象。