ПРОБЛЕМА: Работа с глубоко вложенными указателями в C++
Я определяю эту структуру:
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;
}
};
и эти структуры:
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;
}
};
и затем в моем коде я возвращаю указатель на s_molecule (typedef'd to t_molecule, но все же).
Используя этот указатель, я могу заставить этот код работать:
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;
}
Если я заменю его на:
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;
}
Теперь я получаю неприятные сегфо...
Не помещать слишком много здесь, но я также получаю segfaults, когда я пытался сделать это:
std::cout << "Bond ATOMS : "
<< (*current_molecule).my_bonds[0].particle_1->name
<< std::endl
Опять же, current_molecule - это указатель на структуру s_molecule, которая содержит массивы структур, которые, в свою очередь, либо напрямую имеют переменные, либо являются указателями. Я не могу заставить работать эти несколько уровней косвенности. Предложения по исправлению этих ошибок.
К вашему сведению, я компилирую на Linux Centos 5.4 с g++ и использую собственную систему makefile.
4 ответа
Снова, на эту проблему ответили здесь: странная проблема Указателя в C++ DeadMG. Извините за двойной пост.
Дикое предположение: вы используете общие библиотеки. Я помню, как испытывал трудности с передачей STL-контейнеров через границы разделяемой библиотеки.
Джейсон (OP) спросил в комментарии Дэвида Родригеса:
Вы возвращаете указатель на локальную переменную?
Джейсон ответил:
Нет, это ptr для переменной класса. Класс существует очень много (он содержит функцию, которая возвращает молекулу).
Если вы не говорите об истинной переменной класса (квалифицируется как static
) тот факт, что класс существует, не имеет к этому никакого отношения. Экземпляры класса существуют, и они могли бы перестать существовать, даже если вы просто вызвали для них функцию.
Таким образом, вопрос заключается в следующем:
- Имеет ли экземпляр класса, который возвратил указатель
current_molecule
все-еще существует? - Или
current_molecule
квалифицируется какstatic
быть истинной переменной класса?
Если ответ на оба вопроса "нет", вы находитесь в неопределенном округе.
На этом этапе становится очень важным, чтобы вы опубликовали исходный код, который мы можем использовать здесь, чтобы фактически воспроизвести проблему; он может быть расположен в источнике, который вы нам не показываете.
@sbi Спасибо за хороший совет! Я полагаю, что вы правы - оператор перегруженного назначения не нужен и должен быть отменен.
Я следовал подходу комментирования вещей и очень запутался. В основном, в функции, которая передает указатель на мою конкретную молекулу в основную функцию для печати, я могу видеть все данные в этой молекуле (связи, частицы, имя и т. Д.), Прекрасно печатая с помощью cout's.
Как только я передаю его в main как ptr, если я использую этот ptr с итератором, я получаю segfault. Другими словами. Кроме того, по какой-то причине данные о связях (которые я могу свободно распечатать в своей функции, которая возвращает указатель) также могут быть ошибочными, если я попытаюсь их напечатать, даже если я использую [] для индексации вектора связей (который работает для частицы вектор).
Это лучшая информация, которую я могу дать сейчас.