Я столкнулся с ОЧЕНЬ неприятной проблемой с указателем. Я ранее разместил здесь:
TOUGH: Работа с глубоко вложенными указателями в C ++
Но этот пост стал слишком длинным и устаревшим, поэтому я решил сделать репост с более подробной информацией.
Вот мой заголовочный файл, который определяет мои типы:
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#define USE_3D_GEOM
//#define USE_2D GEOM
#define DEBUG
#ifdef USE_3D_GEOM
#define DIMENSIONS 3
#elif USE_2D_GEOM
#define DIMENSIONS 2
#else
#define DIMENSIONS 1
#endif
#ifndef _COMMON_H
#define _COMMON_H
template<class T>
inline T from_string(const std::string& s)
{
std::istringstream stream (s);
T t;
stream >> t;
return t;
};
template <class T>
inline std::string to_string (const T& t)
{
std::stringstream ss;
ss << t;
return ss.str();
}
enum e_ensemble_kind
{
MICROCANONICAL,
CANONICAL,
NVT,
GRAND_CANONICAL,
NPT,
NVE
};
enum e_potential_kind
{
HARD_SPHERE,
SQUARE_WELL,
LENNARD_JONES
};
enum e_file_types
{
MC_SIMPLE,
NAMD,
GROMACS,
CHARMM
};
#ifdef USE_3D_GEOM
typedef struct s_coordinates t_coordinates;
#endif
#ifdef USE_2D_GEOM
typedef struct s_coordinates t_coordinates;
#endif
typedef struct s_particle t_particle;
typedef struct s_bond t_bond;
typedef struct s_angle t_angle;
typedef struct s_dihedral t_dihedral;
typedef struct s_molecule t_molecule;
typedef struct s_lj_param t_lj_param;
typedef struct s_bond_param t_bond_param;
typedef struct s_angle_param t_angle_param;
typedef struct s_dih_param t_dih_param;
typedef struct s_lookup_tab t_lookup_tab;
#ifdef USE_3D_GEOM
struct s_coordinates
{
double x;
double y;
double z;
s_coordinates& operator+(const s_coordinates &to_add)
{
x += to_add.x;
y += to_add.y;
z += to_add.z;
return *this;
}
s_coordinates& operator-(const s_coordinates &to_subtract)
{
x -= to_subtract.x;
y -= to_subtract.y;
z -= to_subtract.z;
return *this;
}
s_coordinates& operator=(const s_coordinates &to_assign)
{
x = to_assign.x;
y = to_assign.y;
z = to_assign.z;
return *this;
}
bool operator==(const s_coordinates &to_assign)
{
return x == to_assign.x && y == to_assign.y && z == to_assign.z;
}
};
#endif
#ifdef USE_2D_GEOM
struct s_coordinates
{
double x;
double y;
s_coordinates& operator+(const s_coordinates &to_add)
{
x += to_add.x;
y += to_add.y;
return *this;
}
s_coordinates& operator-(const s_coordinates &to_subtract)
{
x -= to_subtract.x;
y -= to_subtract.y;
return *this;
}
s_coordinates& operator=(const s_coordinates &to_assign)
{
x = to_assign.x;
y = to_assign.y;
return *this;
}
bool operator==(const s_coordinates &to_assign)
{
return x == to_assign.x && y == to_assign.y;
}
};
#endif
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;
}
};
struct s_angle
{
t_particle * particle_1;
t_particle * particle_2;
t_particle * particle_3;
std::vector<t_angle_param>::iterator my_angle_kind_iter;
s_angle& operator=(const s_angle &to_assign)
{
particle_1 = to_assign.particle_1;
particle_2 = to_assign.particle_2;
particle_3 = to_assign.particle_3;
my_angle_kind_iter = to_assign.my_angle_kind_iter;
return *this;
}
};
struct s_dihedral
{
t_particle * particle_1;
t_particle * particle_2;
t_particle * particle_3;
t_particle * particle_4;
std::vector<t_dih_param>::iterator my_dih_kind_iter;
s_dihedral& operator=(const s_dihedral &to_assign)
{
particle_1 = to_assign.particle_1;
particle_2 = to_assign.particle_2;
particle_3 = to_assign.particle_3;
particle_4 = to_assign.particle_4;
my_dih_kind_iter = to_assign.my_dih_kind_iter;
return *this;
}
};
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;
}
};
struct s_lj_param
{
double epsilon;
double sigma;
std::string atom_kind_name;
};
struct s_bond_param
{
std::string atom_1;
std::string atom_2;
double bond_coeff;
double default_length;
};
struct s_angle_param
{
std::string atom_1;
std::string atom_2;
std::string atom_3;
double angle_coeff;
double default_angle;
};
struct s_dih_param
{
std::string atom_1;
std::string atom_2;
std::string atom_3;
std::string atom_4;
std::vector<double> dih_coeff;
std::vector<unsigned int> n;
std::vector<double> delta;
};
struct s_lookup_tab {
std::string name;
int code;
};
#endif /*_COMMON_H*/
А вот вызов, который я делаю, чтобы добавить переменную типа t_molecule (см. Заголовок выше для определения t_molecule) к массиву молекул.
void Molecule_Manager_Main::add_molecule(const t_molecule new_molecule)
{
std::cout << "TYPE :" << new_molecule.res_name << std::endl;
std::cout << "3: BOND PARTICLE 1 : "
<< new_molecule.my_bonds[new_molecule.my_bonds.size()-1].particle_1->name
<< std::endl;
std::cout << "3: BOND PARTICLE 2 : "
<< new_molecule.my_bonds[new_molecule.my_bonds.size()-1].particle_2->name
<< std::endl;
std::cout << "3: BOND ITER CONST : "
<< new_molecule.my_bonds[new_molecule.my_bonds.size()-1].my_bond_kind_iter->bond_coeff
<< " "
<< new_molecule.my_bonds[new_molecule.my_bonds.size()-1].my_bond_kind_iter->default_length
<< std::endl;
my_molecules.push_back(new_molecule);
std::cout << "99: INDEX : " << my_molecules.size()-1 << std::endl;
std::cout << "TYPE :" << my_molecules[my_molecules.size()-1].res_name << std::endl;
std::cout << "4: BOND PARTICLE 1 : "
<< my_molecules[my_molecules.size()-1].my_bonds[my_molecules[my_molecules.size()-1].my_bonds.size()-1].particle_1->name
<< std::endl;
std::cout << "4: BOND PARTICLE 2 : "
<< my_molecules[my_molecules.size()-1].my_bonds[my_molecules[my_molecules.size()-1].my_bonds.size()-1].particle_2->name
<< std::endl;
std::cout << "4: BOND ITER CONST : "
<< my_molecules[my_molecules.size()-1].my_bonds[my_molecules[my_molecules.size()-1].my_bonds.size()-1].my_bond_kind_iter->bond_coeff
<< " "
<< my_molecules[my_molecules.size()-1].my_bonds[my_molecules[my_molecules.size()-1].my_bonds.size()-1].my_bond_kind_iter->default_length
<< std::endl;
add_performed = true;
}
Это прекрасно работает ... печатается строка с именем resname и печатается информация о последней связи в векторе связей. Затем, как только я добавил все мои молекулы. Я называю это:
t_molecule * Molecule_Manager_Main::get_molecule(unsigned int index)
{
std::cout << "TYPE :" << my_molecules[index].res_name << std::endl;
std::cout << "5: BOND PARTICLE 1 : "
<< my_molecules[index].my_bonds[my_molecules[index].my_bonds.size()-1].particle_1->name
<< std::endl;
std::cout << "5: BOND PARTICLE 2 : "
<< my_molecules[index].my_bonds[my_molecules[index].my_bonds.size()-1].particle_2->name
<< std::endl;
std::cout << "5: BOND ITER CONST : "
<< my_molecules[index].my_bonds[my_molecules[index].my_bonds.size()-1].my_bond_kind_iter->bond_coeff
<< " "
<< my_molecules[index].my_bonds[my_molecules[index].my_bonds.size()-1].my_bond_kind_iter->default_length
<< std::endl;
return &(my_molecules[index]);
}
Это сегфолты на линии облигаций.
Я могу сказать по индексам, которые я печатаю на этапе добавления, что я не перезаписываю молекулы, которые нажимаю на вектор (размер растет) ..
Другими словами, кажется, что происходит:
Читать подвектор (работает) -> добавить еще элементы в родительский вектор -> перечитать подвектор (seg-faults)
Эти функции являются ЕДИНСТВЕННЫМИ средствами для добавления переменных молекул к вектору, а переменные молекул добавляются только один раз и не изменяются посмертно в моем текущем тесте.
Есть идеи ???? Заранее спасибо !!