为什么要编译此代码
Why does this code compile
我不明白为什么这段代码编译并运行时没有错误:
#include <iostream>
#include <stdio.h>
#include <Eigen/Dense>
int
main (int argc, char *argv[])
{
typedef Eigen::Matrix<double, 5, 3/*FIXME: Should be 5*/> Matrix5;
Matrix5 test;
test << 2,0,0,1,1,
0,2,0,1,1,
0,0,2,2,2,
0,1,2,0,0,
0,1,1,0,0; // We filled a 5*5 matrix in a 5*3 matrix
//std::cout << "Test matrix:n" << test << std::endl;
return (0);
}
这就是我编译代码的方式:
g++ test_eigen.cpp -o test_eigen -I/usr/include/eigen3 -O3 -DEIGEN_NO_DEBUG
取消对std::cout
的注释,编译,再次运行,就会出现分段错误。我在Ubuntu 14.04上使用的是Eigen 3.2.0-8。
如建议;以下是Valgrind的输出(已评论std::cout
):
$ valgrind ./test_eigen
==12380== Memcheck, a memory error detector
==12380== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==12380== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==12380== Command: ./test_eigen
==12380==
==12380==
==12380== HEAP SUMMARY:
==12380== in use at exit: 0 bytes in 0 blocks
==12380== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==12380==
==12380== All heap blocks were freed -- no leaks are possible
==12380==
==12380== For counts of detected and suppressed errors, rerun with: -v
==12380== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
写入超过数据结构的已分配边界(例如,将5x5矩阵写入已分配的5x3)是未定义的行为。它可能会崩溃,也可能不会崩溃,不幸的是,它甚至可能在没有可见错误的情况下运行到完成。
使用valgrind运行您的代码,以精确定位与您描述的类似的内存问题。
我怀疑您编译时禁用了断言。
Eigen重载operator<<
,使矩阵能够用逗号分隔的列表进行初始化。(请注意,这也意味着隐藏在幕后的逗号运算符被覆盖)。逗号分隔的项目列表可以包含数字,但也可以包含向量或其他矩阵。
这种灵活性是有代价的。Eigen在编译时无法判断逗号分隔的列表包含的项目太多或太少。相反,它在运行时检测到项目过多/过少,并通过eigen_assert
进行投诉。如果您在禁用断言的情况下进行编译,则会让过于完整的项列表从SIGABRT变为未定义的行为。
这种事情总是发生在未定义的行为中,添加一条语句可以神奇地让代码无错误地运行。不要把这看作是一切正常的迹象。它只是碰巧在运行。未定义的行为总是不好的。在某些情况下,它"有效"并不意味着下次使用该程序时,代码不会重新格式化硬盘。
为什么要编译此代码?
因为编译器将无法知道在编译时您传递给operator<<
的元素数量。该信息仅在运行时可用。
相关文章:
- 如何修复sfml c++代码编译错误
- 尝试用java代码编译和运行c++代码
- 此代码编译良好,但文件未创建?请指出错误
- 为什么我的 BaseClass:Method 代码编译(带有单冒号)?
- 代码编译没有任何输出,入门程序
- 通过Python Distutils(用于Python C扩展)使用可重定位的设备代码编译CUDA代码
- 代码编译但不起作用!cmd窗口只是理想和理想,但什么也没发生
- 无法使用 g++ 使用C++代码编译 C 库
- 如何在Ubuntu中使用Visual Studio代码编译C++代码
- 推力+提升代码编译错误
- C++代码编译,但在 Zorin OS 上运行时显示错误
- 如何在使用模板时将 CPP 代码编译到库文件中
- 是否可以将Visual Studio 2017将C 代码编译到EXE以外的文件类型中
- 使用 Visual Studio for C++ 代码编译错误
- 使用 Android Studio 使用本机代码编译 apk 时,如何在链接处删除 libgnustl_static.
- 使用 Emscripten 将 OpenCV 代码编译C++ Javascript
- 将C 代码编译到独立应用程序.App
- 为什么此代码编译 (C++11) 而没有类型不匹配错误
- 重用编译器前端的结果,以加快多个配置/平台的C++代码编译
- 如何将C++11代码编译为网络汇编