二维阵列中的内存泄漏

时间:2017-11-24 02:08:34

标签: c++ arrays memory-management memory-leaks

我有一个班级:

class Land{
public:
  ~Land() { if(map != nullptr) Clean(); }

  bool Create();
  void PrintMap() const;
  void Clean();
private:
  int rows = 0, columns = 0;
  int **map = nullptr;

  bool CorrectDimensions() const;
  void CreateMap();
  bool FillMap();
};
bool Land::Create() {
  //
  printf("Matrix size:\n");
  if(scanf("%d %d", &(this->columns), &(this->rows) ) != 2 || !CorrectDimensions() )
    return false;

  CreateMap();
  printf("Values:\n");
  return FillMap();
}
void Land::CreateMap() {
  //
  this->map = new int*[rows];

  for(int column = 0; column < this->rows; column++)
    map[column] = new int[this->columns];
}
bool Land::FillMap() {
  //
  for(int row = 0; row < this->rows; row++) {
    for(int column = 0; column < this->columns; column++) {
      if( ! scanf("%d", &(this->map[row][column]) ) ) {
        return false;
      }
    }
  }

  return true;
}
void Land::Clean() {
  //
  for(int row = 0; row < this->rows; row++)
  delete [] this->map[row];
  delete [] this->map;
}

我的司机:

int main() {
  //
  Land l;

  if( ! l.Create() ) {
    IncorrectInput();
    return 1;
  }

  l.PrintMap(); //prints correct output
}

我认为我的计划应该如何运作:

  1. 调用默认构造函数,不需要自定义构造函数。
  2. 检查输入是否满足要求。 如果不是,请返回false,从而完成该计划。内存尚未动态分配(保持在nullptr),没问题。
  3. 如果是,使用calloc创建一个二维数组(我知道我将C与C ++混合,想要使用类,而vector不可用)。< / LI>
  4. 使用扫描值填充该2D阵列。如果扫描值不是整数,则返回false,从而完成程序。
  5. 打印该数组的值。 Const功能。
  6. 完成程序,以便调用析构函数。由于我不知道Create()是否过早结束(calloc之前),我默认将int **map初始化为nullptr。如果我分配,map将不再是nullptr,并且需要被释放。否则,析构函数应该free,这就是Clean()所做的。
  7. Clean()我遵循动态分配和释放的做法。 callocfree遵循其反转模式。调试确认调用了多少calloc个,调用了许多free
  8. 完成所有这些操作后,valgrind仍会报告错误(不是reachable,实际错误)。具体来说:total heap usage: 184 allocs, 23 frees。是什么导致了这个错误,我错过了什么?

    编辑:已初始化的rowscolumns成员。已使用C ++ calloc()new更改了delete

1 个答案:

答案 0 :(得分:0)

没有内存泄漏。 calloc不会抛出异常。

BTW,在Land::CreateMap和meny其他地方检测到空指针deference。 不要忘记检查calloc

的返回值

更新

例如,

class foo {
  int* p1;
  int* p2;
  foo()
  {
    p1 = new int;
    p2 = new int;
  }
  ~foo()
  {
    delete p1;
    delete p2;
  }
};
int main()
{
  foo val;
}

foo的Ctor中,当p2 = new int;抛出异常时,foo 的Dtor将不会调用,因此,任何人都可以删除p1

因此,当您想在ctor中使用非noexcept运算符new分配内存时,必须使用RAII包装器。 C ++ 11或更高版本具有RAII wapper类来分配内存,即std::unique_ptrstd::shared_ptr

BTW,

  

矢量不可用

您使用的环境是什么?