我今天得到了一个未初始化的指针问题。不幸的是,它在释放后引起了核心转储。
这里是示例代码,函数print_request()是新代码,此函数可以被其他几个函数使用:
// def.h
struct INFO {
uint32_t val1;
uint32_t val2;
};
struct INFO_LIST {
uint32_t id;
struct INFO * data;
};
// util.cpp
void print_request(const struct INFO_LIST req)
{
fprintf(stdout, "%u\t%u\t%u\n", req.id, req.data->val1, req.data->val2);
}
// A.cpp
int parse_ie(...)
{
// ...
struct INFO_LIST req;
req.id = 10;
req.data = new INFO();
req.val1 = 101;
req.val2 = 102;
print_request(req);
// ...
}
// B.cpp
int parse_chrome(...)
{
// ...
struct INFO_LIST req;
req.id = 20;
print_request(req); // core dump here!
// ...
}
这就是我所做的:
我已经修改了print_request()的单元测试,但是我忘了有一个未初始化的指针,而函数parse_chrome()使用它。
我使用静态代码分析工具(例如cppcheck)对代码进行分析,并且没有错误或警告。
代码审核后仍然会被忽略。
所以,我想知道:
有什么好的工具可以在C ++中检测未初始化的指针吗?
如何避免在C ++中使用未初始化的指针?
任何建议都将不胜感激,谢谢!
PS,我想编写统一函数来调用指针,但这会花费很多时间。
PPS。抱歉,变量" req"不是指针。我的错。
答案 0 :(得分:0)
您已在第INFO_LIST * req;
行创建了一个结构指针,删除*
来代替创建结构。目前,您正在使用裸指针(类型为struct INFO_LIST)。
答案 1 :(得分:0)
如何避免使用c ++空指针?
你的代码看起来像c,对我来说。语言不同,选择其中一种。
关于你的问题标题:
在C ++中,您可以使用测试的非nullptr值:
if(ptr) ptr->doSomething();
else doSomethingElse();
注意指针是POD,必须明确初始化。
所以
MyObject* ptr = new MyObject; // default ctor
assert(nullptr != ptr); // check for success
或
MyObject* ptr = nullptr;
// later code sets the pointer to something
我更喜欢使用稍微清晰一点:
if(nullptr != ptr) ptr->doSomething();
答案 2 :(得分:0)
首先,将默认构造函数添加到INFO_LIST
:
struct INFO_LIST {
uint32_t id;
struct INFO * data;
INFO_LIST() : id(0), data(nullptr) { ; }
};
第二:在print_request
中抛出异常:
// util.cpp
void print_request(const struct INFO_LIST req)
{
if (! req.data->val1 || ! req.data->val2)
throw (std::runtime_error ("Uninitialized pointers"));
fprintf(stdout, "%u\t%u\t%u\n", req.id, req.data->val1, req.data->val2);
}
如果你想在编译时捕获它:
struct INFO_LIST {
uint32_t id;
struct INFO * data;
INFO_LIST (struct INFO* d) : data(d) { ; }
private:
INFO_LIST () { ; }
};
现在,如果在没有初始化INFO_LIST
指针的情况下尝试构造data
,则在编译时会出现错误。