c++ - 在代码块中运行发布版本时出现段错误,但运行调试版本时不会出现段错误

标签 c++ linux gcc codeblocks

我正在使用代码块:

Release 13.12 rev 9501 (2013-12-25 18:25:45) gcc 4.8.2 Linux/unicode - 64 bit

在以下系统上:

Linux Mint 17.3 Cinnamon (version 2.8.7) 64-bit
Intel Core i7-4790
NVIDIA GeForce GTX 750 Ti

当我将选定的目标设置为“调试”并运行我的代码时,它工作得很好。我已经运行了很多次了,没有任何问题。但是,当我选择“发布”目标并从命令提示符运行程序时,经常会出现段错误。

我的C++程序大约有一千行,我不知道程序的哪一部分导致了段错误。所以我不知道现阶段哪些代码是相关的(当我有更多信息时,我会在这里发布一些代码)。它确实使用了指针和动态数据结构。我猜测某些东西没有正确初始化,但我不知道如何调试“发布”版本。我没有更改任何编译器或链接器设置的默认值。 “发布”版本中的哪些不同可能会导致此问题?

(更新)按照 Nathan 的建议,我能够隔离段错误。有一个 for 循环,但在某些情况下,该循环的上限(结束索引)没有被初始化,大致如下:

void fnProc(bool var_val, int inp_val, int test_val, int st_idx, int lim_idx, int xarr[])
{
    int idx, end_idx;
    if (test_val > inp_val)
        end_idx = someFn(inp_val, lim_idx, xarr);
    if (!var_val)
        for (idx = st_idx; idx <= end_idx; idx++)
            xarr[idx] = 0;
}

通过将“end_idx”变量初始化为零(“st_idx”始终大于一),我能够解决该问题:

void fnProc(bool var_val, int inp_val, int test_val, int st_idx, int lim_idx, int xarr[])
{
    int idx, end_idx;
    if (test_val > inp_val)
        end_idx = someFn(inp_val, lim_idx, xarr);
    else
        end_idx = 0;
    if (!var_val)
        for (idx = st_idx; idx <= end_idx; idx++)
            xarr[idx] = 0;
}

当变量未像这样初始化时,是否可以让代码块/GCC 编译器发出警告?我看到有一个 GCC 选项:-Wuninitialized,但我在代码块中没有看到这个。

最佳答案

Is it possible to get Code Blocks / GCC compiler to issue a warning when a variable has not been initialised like this? I see there is a GCC option: -Wuninitialized, but I don't see this in Code Blocks

您可以添加编译器设置中不可用的任何编译器选项 -> 编译器标志 从工作区 TreeView 导航菜单 您的项目 -> 构建选项 -> {调试|发布} -> 编译器设置 -> 其他编译器选项 并将它们列在文本框中。

但是,这样添加-Wuninitialized是不必要的,因为它 由 -Wall 启用,并由您使用通常的发布版本的代码激发 优化-O2(或任何高于-O0):-

foo.cpp

extern int someFn(int, int, int[]);

void fnProc(bool var, int inp_val, int test_val, int st_idx, int lim_idx, int xarr[])
{
    int idx, end_idx;
    if (test_val > inp_val)
        end_idx = someFn(inp_val, lim_idx, xarr);
    if (!var)
        for (idx = st_idx; idx <= end_idx; idx++)
            xarr[idx] = 0;
}

使用 g++ 5.2:

$ g++ -O2 -Wall -c foo.cpp
foo.cpp: In function ‘void fnProc(bool, int, int, int, int, int*)’:
foo.cpp:5:14: warning: ‘end_idx’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     int idx, end_idx;
              ^

这至少可以追溯到 GCC 4.4.7

-Wall 通过 Code::Blocks 编译器设置 -> 编译器标志菜单启用 通过勾选警告项 -> 启用所有常见编译器警告

在 Code::Blocks 16.01(我目前拥有的)中,即使此设置也是不必要的 因为默认情况下为调试和发布配置启用了 -Wall, 因此,警告会适本地出现在默认的 Code::Blocks 控制台项目发布版本中 foo.cpp:-

-------------- Build file: Release in deleteme (compiler: GNU GCC Compiler 5.2)---------------

g++-5 -Wall -fexceptions -O2  -c /home/imk/develop/deleteme/foo.cpp -o obj/Release/foo.o
/home/imk/develop/deleteme/foo.cpp: In function ‘void fnProc(bool, int, int, int, int, int*)’:
/home/imk/develop/deleteme/foo.cpp:5:14: warning: ‘end_idx’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     int idx, end_idx;
              ^
Process terminated with status 0 (0 minute(s), 0 second(s))
0 error(s), 1 warning(s) (0 minute(s), 0 second(s))

据我记得,-Wall 一直是默认的 GCC 选项 Code::Blocks 已经使用了大约 6 年,但也许我错了。

关于c++ - 在代码块中运行发布版本时出现段错误,但运行调试版本时不会出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36629053/

相关文章:

c++ - 内存分配运算符和表达式

gcc - 如何下载 GCC 源代码?

字符数组下标警告

c++ - 我可以访问地址零吗?

c++ - for循环重用变量的位置

linux - 如何使用 MOD_XML_CURL 通过 HTTP GET 方法检索 SIP 凭据

c - 如何获取大页面的物理地址

linux - 如何从 Linux shell 访问 BIOS ROM 二进制文件

无法解决 NetBeans 中的标识符问题

c++ - QSettings 实例失败