タフ:C ++の深くネストされたポインターに対処する
-
29-09-2019 - |
質問
この構造を定義します。
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へのポインターを返します(tipedef'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;
}
私は今、厄介なセグフォールトを手に入れます...
ここにあまりにも多くを入れないようにしますが、これをやろうとしたときにもセグフォールトを取得しています。
std::cout << "Bond ATOMS : "
<< (*current_molecule).my_bonds[0].particle_1->name
<< std::endl
繰り返しますが、current_moleculeは、s_molecule構造へのポインターであり、構造の配列を含みます。これらの複数の間接的な層を動作させることはできません。これらのセグメントの修正に関する提案。
解決 4
繰り返しますが、この問題はここで答えられました:C ++の奇妙なポインターの問題Deadmgによって。二重投稿でごめんなさい。
他のヒント
@SBI良いアドバイスをありがとう!私はあなたが正しいと信じています - 割り当て過負荷のオペレーターは不要であり、廃棄する必要があります。
私はものにコメントするアプローチに従いましたが、非常に混乱しています。基本的に、私の特定の分子へのポインターを印刷する主な関数に渡す関数では、その分子(結合、粒子、名前など)のすべてのデータが完全に表示され、カウトで印刷されます。
PTRとしてメインに渡すと、そのPTRをイテレーターで使用すると、segfaultが表示されます。言い換えると。また、何らかの理由で、ボンドデータ(ポインターに戻る関数で自由に印刷できます)も印刷しようとすると、[]を使用して結合のベクトルをインデックス化しても(粒子で動作します。ベクター)。
それは私が今のところ与えることができる最高の情報です。
ワイルド推測:共有ライブラリを使用していますか。共有ライブラリの境界を越えてSTLコンテナーをやり取りするのに苦労したことを覚えています。
ジェイソン(OP)は、デビッド・ロドリゲスのコメントで尋ねられました。
ローカル変数へのポインターを返していますか?
ジェイソンは答えました:
いいえ、クラス変数へのPTRです。クラスは非常に存在しています(分子を返す関数が含まれています)。
あなたが真のクラス変数について話しているのでなければ( static
)、その事実 クラス 存在することはそれとはあまり関係がありません。 インスタンス クラスが存在し、あなたがそれらに関数を呼んだとしても、彼らは存在しなくなったかもしれません。
そのため、問題は次のとおりです。
- どうしますか 実例 ポインターを返したクラスの
current_molecule
まだ存在しますか? - またはそうです
current_molecule
として資格がありますstatic
, 、つまり、真のクラス変数ですか?
両方の質問に対する答えが「いいえ」の場合、あなたは未定義の郡にいます。
この時点で、実際に問題を再現するためにここで使用できるソースコードを投稿することが非常に重要になります。それはあなたが私たちに見せていないソースにあるかもしれません。