我的代码有问题,有一些非常奇怪的症状。
代码是在我的电脑上编译的,版本如下:
一个。 GCC 版本:4.4.2
CMAKE 版本:2.8.7
QNX(操作系统)版本:6.5.0
并且代码在释放一些内存并退出函数时出现段错误(不会死于任何代码,只是在函数退出时)。
奇怪的是:
代码在 Release模式而非 Debug模式下执行:
一个。代码是线程化的,因此这表明存在竞争条件。
我无法通过将其置于 Debug模式来进行调试。
在同事机器上编译时所有的东西都相同版本的代码没有这个问题。
一个。奇怪的是,同事的代码可以工作,而且在他的机器上编译生成的二进制文件(相同)大约大 6mB。
现在烦人的是,我无法发布代码,因为它太大而且不适合工作。但是任何人都可以指出我解决这个问题的途径。
由于我使用的是 QNX,因此我的调试工具受到限制,我无法使用 Valgrind,而且由于 QNX 不支持它,GDB 并没有真正帮助。
我正在寻找遇到类似/相同问题的任何人,以及原因是什么以及他们是如何解决的。
编辑:
Sooo...我发现了它是什么,但我仍然对它是如何发生的感到有点困惑。
罪魁祸首代码是这样的:
Eigen::VectorXd msBb = data.modelSearcher->getMinimumBoundingBox();
getMinimumBoundingBox
的定义是这样的:
Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();
它返回一个始终初始化为 VectorXd output(6, 1)
的 VectorXd。于是我马上想到,对了,一定是因为VectorXd没有被初始化,而是改成了这样:
Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();
但这没有用。事实上,我必须通过将函数的定义更改为此来修复它:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
以及对此的调用
Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);
那么现在是新问题:
什么鬼?为什么第一个更改不起作用但第二个更改起作用,为什么我必须通过引用传递?哦,还有个大问题,当我的同事编译它并运行它时,这到底是怎么回事?这是一个直接的内存错误,当然它不应该取决于哪台计算机编译它,特别是因为编译器和所有其他重要的东西都是一样的!??
感谢您的帮助。
最佳答案
... the binary created from compiling on his machine, which is the same, is about 6mB bigger
值得弄清楚有什么区别(即使只是他的构建隐藏了一个真正的错误,而你的暴露了一个真正的错误):
- 仔细检查您正在编译完全相同的代码(没有未提交的本地更改,包含搜索路径中没有额外的标题等)
- 通过在 cmake 中向您的 gcc 参数添加一个
-E
开关来进行三次检查,因此它将使用与常规编译相同的包含路径来预处理您的文件;区分预处理器输出
- 通过在 cmake 中向您的 gcc 参数添加一个
- 比较来自
nm
或objdump
的输出或任何你必须为你的两个链接的可执行文件做的事情:如果某个系统或第 3 方库在一个盒子上是不同的版本,它可能会出现在这里 - 比较
ldd
的输出,如果它是动态链接的,确保它们都获得相同的库版本- 如果可能的话,也比较它实际上在运行时获得的库版本。希望您可以执行以下操作之一:运行
pldd
,比较/proc/pid/map
中的.so
条目,在下运行进程>strace
/dtrace
/truss
并比较运行时链接器事件
- 如果可能的话,也比较它实际上在运行时获得的库版本。希望您可以执行以下操作之一:运行
至于代码...如果这不起作用:
Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();
// ...
Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();
这样做:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
// ...
Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);
您可能对赋值运算符有疑问。如果它执行浅拷贝并且 vector 中有动态分配的内存,您最终会得到两个持有相同指针的 vector ,并且它们都将free
/delete
它。
请注意,如果根本未定义运算符,则默认执行此浅拷贝。
关于c++ - 具有相同编译器的相同程序代码会导致不同的二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13409029/