私は問題があります。すべてを試すのに約5時間を費やしていますが、それを正しく再現することさえできず、単純化された元のソースコードが含まれています。その程度までお詫び申し上げますが、私がこれまでに知り得たすべての関連情報を含めたかったのです。これは私が完全に無力で、あなたの助けを親切に要求している数回のうちの1つです。どんなアイディアも大歓迎です。また、問題に少なくともいくらかの光をもたらすことができるコメント。この場合の動作は私にとって完全な謎です。非constメソッドを呼び出さずにプライベートメンバーを変更するにはどうすればよいですか?
私はUbuntuのQtCreatorでプログラミングしています。私は真の解に進化するべき候補解の集団を使って数学的問題を解決するためのフレームワークを開発しようとしています。
関わる3つのクラスがあります:人口、PopulationMemberと問題:
class PopulationMember
{
QVector<Number> x_;
QVector<Number> y_;
Population* population_; EDIT: Sorry, this is a pointer
void evaluate();
friend class Population;
};
class Population
{p
public:
QList<PopulationMember*> members_; // created on the heap
Problem* problem_; // created on the heap
const Problem* readProblem() const;p
void evaluate();
void report() const;
...
};
class Problem
{
public:
void evaluate(PopulationMember&)const;
};
通常私のプログラムは、人口がそのさまざまなメソッドを呼び出しループで実行されますが。それらの1つはPopulation :: evaluate()です。 Populationの新しいメソッドを導入するまで私のプログラムは素晴らしかったです。
for (int i = 1; i != 101; ++i)
{
Population->evaluate();
Population->someMethod1();
Population temp = Population->clone();
temp->someMethod2();
Population->append(temp);
Population->someNewMethod();
Population->someSorting();
if (i % 10 == 0)
Population->report();
}
次に、プログラムの途中でセグメント化エラーが発生します。最も不思議なことは、集団が報告書を実行した後、10回のループの後でしか起こらないということです。また、いくつかの実験の後、report()メソッドから何らかのソート(文字列)を動的に割り当てる必要があるすべての操作を除外しても、エラーは発生しません。逆にソート方法を無効にすると(std :: sortまたはqSortのどちらかを使います)、問題は停止します。また、一時的な人口によって行われた行動を残しても問題はありません。そこで私はプログラムをデバッグし始めました。私は10ループを完了させ、ステップバイステップでデバッグを開始しました。私はPopulation-> evaluate()に行きました。
void Population::evaluate()
{
for (Iterator it = begin(); it != end(); ++it)
{
std::cout << problem_; // debug see bellow:
(*it) -> evaluate(); // If I change to problem_->evaluate(**it); the program works.
}
}
デバッグ:プリントアウト ADDRESは0xbffff628あります。これは、前の10 *人口_-> members_.count()の出力と同じです。
私は(* it) - > evaluate();内部に入ります。ここで私は、アセンブリコードに切り替える:
864 (*it) -> evaluate();
0x805380c <+122>: lea -0x10(%ebp),%eax
0x805380f <+125>: mov %eax,(%esp)
0x8053812 <+128>: call 0x8055d84 <QList<PopulationMember*>::iterator::operator*() const>
0x8053817 <+133>: mov (%eax),%eax
0x8053819 <+135>: mov %eax,(%esp)
0x805381c <+138>: call 0x805ae08 <PopulationMember::evaluate()>
私は最後の命令での関数の呼び出し中に入ります。私はこれを行う瞬間、問題のすべての属性_は私のデバッガによればアクセスできない。 この時点ではすべてが失われています。
void PopulationMember::evaluate()
{
population_ -> readProblem() -> evaluate(*this);
}
135 {
0x805ae08 <+000>: push %ebp
0x805ae09 <+001>: mov %esp,%ebp
0x805ae0b <+003>: sub $0x18,%esp
136 population_ -> readProblem() -> evaluate(*this);
0x805ae0e <+006>: mov 0x8(%ebp),%eax
0x805ae11 <+009>: mov 0x4(%eax),%eax
0x805ae14 <+012>: mov %eax,(%esp)
0x805ae17 <+015>: call 0x8051bc4 <Population::readProblem() const>
0x805ae1c <+020>: mov 0x8(%ebp),%edx
0x805ae1f <+023>: mov %edx,0x4(%esp)
0x805ae23 <+027>: mov %eax,(%esp)
0x805ae26 <+030>: call 0x804e962 <Problem::evaluate(PopulationMember&) const>
137 }
0x805ae2b <+035>: leave
0x805ae2c <+036>: ret
0x805ae2d nop
const Problem* Population::readProblem() const
{
std::cout << problem_ << std::endl; // debug see bellow:
return problem_;
}
デバッグ: 最後にproblem_が指しているアドレスが0xbffff780代わりの0xbffff628になります。増分は344
常に発生します。私が3つのすべてのクラスのサイズが100未満であるので、これはもっと難解です。
voidの内部でプログラムがクラッシュする問題:: evaluate(PopulationMember &)const;メソッドを呼び出すことができます。
EDIT:
Population Population::clone()
{
Population temp(*this);
return temp;
}
Population::Population(const Population& population)
{
this->setProblem(population.problem_);
Population::ConstIterator cit;
for (cit = population.constBegin(); cit != population.constEnd(); ++cit)
this->addCopy(*cit);
this->ownsMembers_ = true;
}
void Population::addCopy (PopulationMember* populationMember)
{
PopulationMember *temp = new PopulationMember(*populationMember); // Memberwise
temp -> population_ = this;
members_.push_back(populationMember);
}
Population::~Population()
{
if (ownsMembers_)
foreach (PopulationMember* X, members_)
delete X;
}
void Population::append(Population& population)
{
if (population.ownsMembers_)
{
members_.append(population.members_);
population.ownsMembers_ = false;
}
else
members_.append(population.members_);
}
は、問題を単純化することができます方法はありますか? Clone()メソッドを見せてもらえますか? –
valgrindを試しましたか? –
人口母集団::クローン()const { 人口temp(* this); 戻り値。 } –