c++ - 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++,而不是 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]
如果没有,那么您应该确保启用了足够的警告。
推荐阅读
- django - 使用打印语句对已关闭文件进行 I/O 操作
- python - 如何在 Pyspark 中捕获日志级别的错误和警告?
- reactjs - 即使在重新渲染之后,React 组件也不会渲染新状态
- asp.net-core - SignalR .NET Core 3.x 替代 IHubProxy
- arrays - 如何用可变数据量的总和填充一列?
- multithreading - 释放线程并删除与该线程关联的文件
- r - R将单列拆分为多行
- android - 如何从应用程序android将变量发送到sql请求
- python - 我可以使用嵌套的 for 循环遍历列表中的完整字符串吗?
- syslog - Fluentd 带有 Syslog 的无效时间格式