views:

221

answers:

4

I define this structure:

struct s_molecule
{
  std::string res_name;
  std::vector<t_particle> my_particles;
  std::vector<t_bond> my_bonds;
  std::vector<t_angle> my_angles;
  std::vector<t_dihedral> my_dihedrals;

  s_molecule& operator=(const s_molecule &to_assign)
  {
    res_name = to_assign.res_name;
    my_particles = to_assign.my_particles;
    my_bonds = to_assign.my_bonds;
    my_angles = to_assign.my_angles;
    my_dihedrals = to_assign.my_dihedrals;
    return *this;
  }
};

and these structures:

typedef struct s_particle
{
  t_coordinates position;
  double charge;
  double mass;
  std::string name;
  std::vector<t_lj_param>::iterator my_particle_kind_iter;

  s_particle& operator=(const s_particle &to_assign)
  {
    position = to_assign.position;
    charge = to_assign.charge;
    mass = to_assign.mass;
    name = to_assign.name;
    my_particle_kind_iter = to_assign.my_particle_kind_iter;
    return *this;
  }
} t_particle;

struct s_bond
{
  t_particle * particle_1;
  t_particle * particle_2;
  std::vector<t_bond_param>::iterator my_bond_kind_iter;

  s_bond& operator=(const s_bond &to_assign)
  {
    particle_1 = to_assign.particle_1;
    particle_2 = to_assign.particle_2;
    my_bond_kind_iter = to_assign.my_bond_kind_iter;
    return *this;
  }
};

and then in my code I return a pointer to an s_molecule (typedef'd to t_molecule, but still).

Using this pointer I can get this code to work:

for  (unsigned int i = 0;
      i < current_molecule->my_particles.size();
      i++)
    {
      std::cout << "Particle " 
        << current_molecule->my_particles[i].name << std::endl
            << "Charge: " 
        << current_molecule->my_particles[i].charge << std::endl
        << "Mass: " 
        << current_molecule->my_particles[i].mass << std::endl
        << "Particle Kind Name: " 
        << (*current_molecule->my_particles[i].my_particle_kind_iter).atom_kind_name 
        << std::endl
        << "x: " << current_molecule->my_particles[i].position.x 
        << " y: " << current_molecule->my_particles[i].position.y
    #ifdef USE_3D_GEOM
        << "z: " << current_molecule->my_particles[i].position.z
    #endif
        << std::endl;
    }

If I replace it with:

for  (std::vector<t_particle>::iterator it = current_molecule->my_particles.begin();
      it !=current_molecule->my_particles.end();
      it++)
    {
      std::cout << "Particle " 
        << (*it).name << std::endl
            << "Charge: " 
        << (*it).charge << std::endl
        << "Mass: " 
        << (*it).mass << std::endl
        << "Particle Kind Name: " 
        << (*(*it).my_particle_kind_iter).atom_kind_name 
        << std::endl
        << "x: " << (*it).position.x 
        << " y: " << (*it).position.y
    #ifdef USE_3D_GEOM
        << "z: " << (*it).position.z
    #endif
        << std::endl;
    }

I now get nasty segfaults...

Not to put too much here, but I'm also getting segfaults when I tried to do this:

std::cout << "Bond ATOMS : " 
          << (*current_molecule).my_bonds[0].particle_1->name
          << std::endl

Again, current_molecule is a pointer to a s_molecule structure, which contains arrays of structures, which in turn either directly have vars or are pointers. I can't get these multiple layers of indirection to work. Suggestions on fixing these segfaults.

FYI I'm compiling on Linux Centos 5.4 with g++ and using a custom makefile system.

A: 

@sbi Thanks for the good advice! I believe you are right -- the assignment overloaded operator is unnecessary and should be scrapped.

I've followed the approach of commenting out stuff and am very confused. Basically in the function that passes the pointer to my particular molecule to the main function to print, I can see all the data in that molecule (bonds, particles, name, etc) perfectly, printing with cout's.

Once I pass it to the main as a ptr, if I use that ptr with an iterator I get a segfault. In other words. Also for some reason the bond data (which I can freely print in my funct that returns to the pointer) also segfaults if I try to print it, even if I use the [] to index the vector of bonds (which works for the particle vector).

That's the best info I can give for now.

Jason R. Mick
1) Use the "edit" function to update your question instead of posting answers (which aren't). 2) If you've simplified the code, don't be afraid to replace your original code example with the simplified one.
DevSolar
Are you returning a pointer to a local variable? If you are doing that the object will be destroyed before you can dereference the pointer, and that will be UB --which means it will crash or not depending on the mood of the system.
David Rodríguez - dribeas
@DevSolar. I'm sorry :( Searched for a delete button but didnt see one. It was like 3 a.m. Definitely will work on simplified version later@David No its a ptr to a class variable. The class is very much in existence (it contains the function that returns the molecule). And like I said... I can at least access some of the members if I used [] indexing, vs. iterator indexing of the vector (this only works with the particle structure, for some reason....
Jason R. Mick
A: 

A wild guess: Are you using shared libraries. I remember having difficulties passing STL-containers back and forth across shared library boundaries.

S.C. Madsen
no. see above for link to solution
Jason R. Mick
A: 

Jason (OP) was asked in a comment by David Rodríguez:

Are you returning a pointer to a local variable?

Jason answered:

No its a ptr to a class variable. The class is very much in existence (it contains the function that returns the molecule).

Unless you're talking of a true class variable (qualified as static), the fact that the class exists doesn't have much to do with it. Instances of a class exist, and they might have ceased to exist even if you just called a function on them.

As such, the question is:

  • Does the instance of the class that returned the pointer current_molecule still exist?
  • Or is current_molecule qualified as static, i.e. being a true class variable?

If the answer to both questions is "no", you're in Undefined County.

At this point, it becomes very important that you post source code that can be used by us here to actually reproduce the problem; it might well be located in source you aren't showing us.

DevSolar
This has been answered in another thread... what was happening was the vector was dynamically resizing when new elements were added, so pointers to sub vector elements in previous elements were getting screwed up. Switching to indices... 99 percent sure that will work!
Jason R. Mick
http://stackoverflow.com/questions/3136586/weird-pointer-issue-in-c/3136667#3136667...sorry about that, should have provided that :DProgram is working like a charm when I switch my pointers to array indices and made some new methods to work based on returning a structure at a particular index!Apparently when the vector resizes, pointers inside structures therein get invalidated...Kudos to DeadMG who figured this out.
Jason R. Mick
A: 

Again, this issue was answered here: http://stackoverflow.com/questions/3136586/weird-pointer-issue-in-c by DeadMG. Sorry for the double post.

Jason R. Mick