Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory changing between two functions calls

Tags:

c++

this is totally strange. I have some code in which I read some parameters from a file and I store them in two stl vectors. I have atoms and residues, and every atom keeps a pointer to his residue. Once finished reading, after declaring a variable, looks like the values in memory changed:

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

Here is the code. I don't really know what I did wrong

#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;

}
like image 484
Guido Polles Avatar asked Dec 03 '10 20:12

Guido Polles


People also ask

How is stack memory used in managing function calls?

Call stack is a dynamic data structure maintained inside the RAM memory by the Operating System. Primary task of Function Call Stack in C is to manage the function calls and how they pass parameters to each other. A call stack is maintained for each task and for each thread.

How does functions affect the stack consumption?

Each called function may increase the amount of data on the stack. Those functions that are called may call other functions, and so on. This again, depends on the snapshot in time of the execution. However, one can produce an approximate maximum increase of the stack by the other called functions.

Are functions on the stack?

When your program calls a function, space is reserved on the stack for the function's return value and it's local variables. If that function calls another function, space will then be reserved for that next function's return value and local variables.


2 Answers

What you're seeing is perfectly normal behaviour -- when you add new elements to a vector, it may get resized, hence all the elements are copied to a new memory location.

If you need a guarantee that existing elements aren't moved in memory, use a different container such as list or set.

like image 179
casablanca Avatar answered Oct 20 '22 19:10

casablanca


std::vector will move memory when it needs more space. It allocates a contiguous block of memory, and when that block fills up, it allocates a bigger block, copies all the elements from the old block to the new one, frees the old block, and moves on.

To prevent the behavior you are seeing, you can do any of a few things to improve your design patter:

1) Change your vectors in main() to store pointers instead of stack options. This way, the object will always be in the same place in memory. 2) Change your class declarations to allow deep copies by implementing a copy-constructor and assignment operator 3) Modify your class heirarchy to remove the circular dependency between your classes. You can do this by having a Residue class, an Atom class, and another class that maps the 2 to each other.

The simplest option will be #1. You'll just need to make sure you clean up memory properly.

like image 30
Zac Howland Avatar answered Oct 20 '22 18:10

Zac Howland