- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个问题。我花了大约 5 个小时尝试一切,但我什至无法正确重现它,所以我包含了简化的原始源代码。对于范围,我深表歉意,但我想包括到目前为止我发现的所有相关信息。这是我感到完全无能为力并恳请您帮助的少数几次之一。欢迎任何想法。还有任何至少可以为此事带来一些启示的评论。这种情况下的行为对我来说完全是个谜。
我在 Ubuntu 的 QtCreator 中编程。我正在尝试开发一个框架来使用候选解决方案的群体来解决数学问题,这些候选解决方案应该演变成真正的解决方案。
涉及 3 个类:Population、PopulationMember 和 Problem:
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;
};
通常我的程序在循环中运行,人们会在循环中调用它的各种方法。其中之一是 Population::evaluate()。在我引入一些新的填充方法之前,我的程序运行得很好。
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() 之后。同样经过一些实验,当我从 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.
}
调试:打印出来的地址是0xbffff628。这与之前的 10 * population_->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()>
我在最后一条指令中进入函数调用。在我这样做的那一刻,根据我的调试器,problem_ 中的所有属性都变得不可访问。在这一点上,一切都失去了。
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
这种情况经常发生。增量是 344。如果我在程序中做一些小改动,地址会改变,但这两个地址之间的差值仍然是 344。这更令人费解,因为我的三个类的大小都小于 100。
程序在 void Problem::evaluate(PopulationMember&)const 内崩溃;一旦涉及到一些逻辑就立即方法。
编辑:
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_);
}
最佳答案
Population Population::clone()
{
Population temp(*this);
return temp;
}
您正在围绕 Population
实例进行大量复制:1. 您正在按值返回本地拷贝,2. 通过分配到另一个本地来再次复制
Population temp = Population->clone();
所有这些实例都获得指向 PopulationMember
的指针,并且 ownsMembers_
始终设置为 true - 这看起来有点可疑,您可能希望在析构函数/构造函数中使用断点进行调试找出每个种群及其成员的生命周期。
编辑:追加方法
void Population::append(Population& population)
{
if (population.ownsMembers_)
{
members_.append(population.members_);
population.ownsMembers_ = false;
}
...
这意味着成员不再指向正确的人口! Population&
的值存储在堆栈中,并在 for
循环结束后被删除,但 PopulationMembers 仍然指向这些 Populations。
编辑:修复
请试试这个:
void Population::append(Population& population)
{
if (population.ownsMembers_)
{
for (cit = population.constBegin(); cit != population.constEnd(); ++cit)
(*cit)-> population_ = this;
population.ownsMembers_ = false;
}
members_.append(population.members_);
}
关于c++ - 如何在不调用非常量方法的情况下更改私有(private)成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8988321/
更新:随意给我反对票,因为问题是我将文件命名为 _stylesheet.html.erb 而不是 _stylesheets.html.erb。我以为我检查了拼写,但显然我没有。我很抱歉浪费了大家的时间
我有一个 Inno Script istaller 在其中运行子 setup.exe 。当向主安装程序提供静默安装参数时,我必须向 setup.exe 提供静默安装参数。 Inno脚本运行命令: [R
我正在尝试在大型数据库中搜索长的、近似的子字符串。例如,一个查询可能是一个 1000 个字符的子字符串,它可能与匹配项相差数百个编辑的 Levenshtein 距离。我听说索引 q-gram 可以做到
我正在尝试在我的应用程序中实现一个非常简单的绘图 View 。这只是我的应用程序的一小部分,但它正在变成一个真正的麻烦。这是我到目前为止所拥有的,但它现在显示的只是莫尔斯电码,如点和线。 - (v
我有一个运行非常慢的 sql 查询,我很困惑为什么。查询是: SELECT DISTINCT(c.ID),c.* FROM `content` c LEFT JOIN `content_meta`
我搜索过这个,但我发现的所有结果对我来说都毫无意义,而且似乎太复杂了。我希望使用 json 或 simplejson 模块来获取对象中字符串的值。 string = '{"name": "Alex"}
我想编写一个流量生成器来复制正在运行的计算机对内存进行的原始读写需求。 但是正在运行的计算机在其内存引用中也显示出(非常强的)局部性,并且在 64 位地址空间中,只会引用非常小范围的地址(事实上,我已
我正在尝试做一个 Project Euler问题,但它涉及添加一个非常大的数字的数字。 (100!) 用Java的int和long太小了。 谢谢你的建议 最佳答案 类 BigInteger看起来它可能
我想在游戏中实现一个物理引擎,以便计算物体在受力时的轨迹。该引擎将根据对象的先前状态计算对象的每个状态。当然,这意味着要在两个时间单位之间进行大量计算才能足够精确。 为了正确地做到这一点,我首先想知道
Edit3:通过将数组的初始化限制为仅奇数进行优化。谢谢@Ronnie! Edit2:谢谢大家,看来我也无能为力了。 编辑:我知道 Python 和 Haskell 是用其他语言实现的,并且或多或少地
背景 我有一个我编写的简单媒体客户端/服务器,我想生成一个非显而易见的时间值,我随每个命令从客户端发送到服务器。时间戳将包含相当多的数据(纳秒分辨率,即使由于现代操作系统中定时器采样的限制,它并不真正
一位招聘软件工程师的 friend 希望我为他开发一个应用。 他希望能够根据技能搜索候选人的简历。 正如您想象的那样,可能有数百、可能数千种技能。 在表格中表示候选人的最佳方式是什么?我在想 skil
我的意思是“慢”,回调类型等待远程服务器超时以有效触发(调用 vimeo 提要,解析它,然后在场景中显示 uiviews) 我大多不明白它是如何工作的。我希望在返回响应后立即从回调中填充我的 View
您好,我正在研究使用快速可靠的生产者消费者队列进行线程切换。我正在使用 VC++ 在 Windows 上工作。 我的设计基于 Anthony Williams队列,基本上就是一个带有 boost::c
我只是想知道您使用 resharper 的经验。我们有一个非常重的 dbml 文件,因为我们的数据库有很多表,每次我需要打开该文件时,我都会收到来自 resharper 的大量异常。以前有人遇到过这个
我目前正在使用 jQuery 中的隐藏/显示功能来帮助从选择框中将表格过滤成组。 实际代码运行良好,但速度非常慢,有时需要一两分钟才能执行。 我切换了代码,所以它使用 css({'display':'
我按顺序调用了以下两个方法(按顺序使用适当的类级别字段) public const string ProcessName = "This is" public const string WindowT
我很难理解描述反射包的文档/示例。我是一名命令式编程老手,但也是一名 Haskell 新手。你能引导我完成一个非常简单的介绍吗? 包裹:https://hackage.haskell.org/pack
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我正在尝试编写一段代码来操作一个很长的文档(超过一百万行)。在这个文本文件中,有固定间隔(每 1003 行)和之间的某些时间戳有我需要的数据,它有 1000 行长,还有一个标题和两个空行,但我不需要。
我是一名优秀的程序员,十分优秀!