如何检测或避免使用C ++未初始化指针?

时间:2016-02-01 03:52:33

标签: c++ pointers

我今天得到了一个未初始化的指针问题。不幸的是,它在释放后引起了核心转储。

这里是示例代码,函数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!

  // ...
}

这就是我所做的:

  1. 我已经修改了print_request()的单元测试,但是我忘了有一个未初始化的指针,而函数parse_chrome()使用它。

  2. 我使用静态代码分析工具(例如cppcheck)对代码进行分析,并且没有错误或警告。

  3. 代码审核后仍然会被忽略。

  4. 所以,我想知道:

    1. 有什么好的工具可以在C ++中检测未初始化的指针吗?

    2. 如何避免在C ++中使用未初始化的指针?

    3. 任何建议都将不胜感激,谢谢!

      PS,我想编写统一函数来调用指针,但这会花费很多时间。

      PPS。抱歉,变量" req"不是指针。我的错。

3 个答案:

答案 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,则在编译时会出现错误。