在C ++中重新分配指针数组,仅使用new和delete

时间:2015-02-23 19:42:58

标签: c++ delete-operator

Carray.h

#ifndef CARRAY_H
#define CARRAY_H

#include "Cell.h"
#include "Pirate.h"

class CArray
{
  public:
    CArray();
    ~CArray();
    int   getSize();
    Cell* get(int);
    int   add(Cell*);
  private:
    int    size;
    Cell** elements;
};

#endif

CArray.cc

CArray::CArray() : size(0)
{ 
  elements = new Cell*[size];
}

CArray::~CArray() 
{
  for (int i=0; i<size; ++i)
    delete elements[i];
}

int CArray::add(Cell* cell)
{
  Cell** tmp = new Cell*[size];
  tmp = elements;
  elements = new Cell*[size+1];

  for (int i = 0; i < size; i++){
    *(elements + i) = *(tmp + i);
  }

  *(elements + size) = cell;

  delete [] tmp;

  size++;
}

这最后一个函数给出了内存泄漏,我不知道在哪里。我所知道的是,每个新的必须与删除匹配,每个new []与删除[]。但是在valgrind中测试它并尝试在重新分配元素之前删除[]元素会给我一个分段错误。如果有人可以解释我哪里出错了,我会是一个快乐的露营者。我很抱歉,如果这是重复的,但我找不到任何具体到足以解决我的问题。

2 个答案:

答案 0 :(得分:2)

您正在为tmp分配,然后通过分配到tmp立即丢失返回给您的指针:

Cell** tmp = new Cell*[size];
tmp = elements;

上面的行会产生内存泄漏,因为new返回的值会在第二行执行后立即丢失。

  

我所知道的是每个新的必须与删除相匹配   new [] with delete []。

这不是唯一要考虑的事情。 new/new[]返回的必须与调用delete/delete[]时使用的相同。

要修复您的功能,您应该这样做:

int CArray::add(Cell* cell)
{
  Cell** tmp = new Cell*[size + 1];

  for (int i = 0; i < size; i++)
    tmp[i] = elements[i];  
  tmp[size] = cell;

  ++size;
  delete [] elements;
  elements = tmp;
  return 1;
}

注意如何将元素复制到tmp数组,然后只需简单地删除旧内存(elements)并分配给{{1新数据。

此外,还有另一个微妙的错误,即您的返回值为elements,但您没有返回任何内容。不从返回值的函数返回值未定义的行为

答案 1 :(得分:1)

在第一行的两行

Cell** tmp = new Cell*[size];
tmp = elements;

你分配内存,在tmp中取新的方向并替换指针。所以,你失去了新的方向。