首页 > 解决方案 > C++/Qt Valgrind 未初始化字节

问题描述

我正在使用 valgrind 来查找和关闭我的应用程序的潜在内存问题,并防止未定义的行为。我的 valgrind 电话看起来像这样

valgrind --leak-check=full --track-origins=yes -v ./app

我无法修复的部分代码是这个:

int App::initSignalHandler(bool dfl)
{
for(size_t sigidx =0; sigidx < sigcount; sigidx++ )
    {
        int signal = stopSignals[sigidx];
        const char *signalName = stopSignalNames[sigidx];      // change signal handler
        struct sigaction new_action;
        sigemptyset (&new_action.sa_mask);
        if(dfl)
            new_action.sa_handler = SIG_DFL;
        else
            new_action.sa_handler = App::stopSignalHandler;
        new_action.sa_flags |= SA_RESTART;
        if(sigaction (signal,&new_action,NULL)!=0)
            qWarning() << Q_FUNC_INFO << "error setting signal handler for : " << signalName;
    }
}

Valgrinds 输出:

==22462== Conditional jump or move depends on uninitialised value(s)
==22462==    at 0x527427C: __libc_sigaction (sigaction.c:53)
==22462==    by 0x117B83: App::initSignalHandler(bool) (app.cpp:127)
==22462==    by 0x116DD7: main (main.cpp:21)
==22462==  Uninitialised value was created by a stack allocation
==22462==    at 0x117B04: App::initSignalHandler(bool) (app.cpp:88)

app.cpp:88 指向函数 initSignalHandler 的左括号所在的行。我查看了这个函数的每个调用。我总是传递布尔值,并且参数也有一个默认的 false 值,所以这不可能是未定义的行为。

app.cpp:127 指向

 if(sigaction (signal,&new_action,NULL)!=0)

我认为这个错误源于 new_actions 结构没有完全初始化。我试图补救的事情: memset(&new_action, 0, sizeof(new_action));但这并没有做任何事情

在某个地方我还找到了一个建议struct sigaction new_action = {0};,但这会导致编译器警告-Wmissing-field-initializers,我不希望有。

所以问题是我应该如何正确初始化 sigaction 结构。我假设这个错误 app.cpp:88 的假定来源也会得到解决?

标签: c++qtvalgrind

解决方案


由于这是 C++,而不是 C,零初始化的正确方法new_object

struct sigaction new_action{};
//                         ^^ Note the brackets here

请注意,struct这里只需要关键字,因为类sigaction和函数之间的名称冲突sigaction


您的函数还有另一个明显的问题需要解决:initSignalHandler被声明为返回 an int,但它不返回任何内容。脱离非void函数的末尾会导致未定义的行为。您的编译器应该通过以下方式警告您:

warning: no return statement in function returning non-void [-Wreturn-type]

如果没有,那么您应该确保启用了足够的警告。


推荐阅读