在C ++中实现增量数组

时间:2012-01-17 13:48:06

标签: c++ arrays dynamic-sizing

我想实现一个可以在添加新值时递增的数组。就像在Java中一样。我不知道该怎么做。谁能给我一个方法?

这是为了学习目的,因此我无法使用std::vector

4 个答案:

答案 0 :(得分:5)

这是一个起点:您只需要三个变量nelemscapacity和指向实际数组的指针。所以,你的课程将从

开始
class dyn_array
{
    T *data;
    size_t nelems, capacity;
};

其中T是您要存储的数据类型;为了额外的功劳,请将其设为模板类。现在实现教科书或Wikipedia page on dynamic arrays上讨论的算法。

请注意,new / delete分配机制不支持像C realloc那样增长数组,因此您实际上将移动data的内容在增加容量时。

答案 1 :(得分:3)

我想借此机会感兴趣一个有趣但有点困难的话题:例外。

  • 如果您自己开始分配内存并随后使用原始指针进行游戏,您将发现自己处于避免内存泄漏的困境中。
  • 即使您将内存的簿记委托给正确的类(比如std::unique_ptr<char[]>),您仍然必须确保更改对象的操作在失败时将其保持一致状态。 / LI>

例如,这是一个简单的类,其中包含不正确的 resize方法(这是大多数代码的核心):

template <typename T>
class DynamicArray {
public:
  // Constructor
  DynamicArray(): size(0), capacity(0), buffer(0) {}

  // Destructor
  ~DynamicArray() {
    if (buffer == 0) { return; }

    for(size_t i = 0; i != size; ++i) {
      T* t = buffer + i;
      t->~T();
    }

    free(buffer); // using delete[] would require all objects to be built
  }

private:
  size_t size;
  size_t capacity;
  T* buffer;
};

好的,所以这很容易(虽然已经有点棘手了)。

现在,你如何在最后推出一个新元素?

template <typename T>
void DynamicArray<T>::resize(size_t n) {
  // The *easy* case
  if (n <= size) {
    for (; n < size; ++n) {
      (buffer + n)->~T();
    }
    size = n;
    return;
  }

  // The *hard* case

  // new size
  size_t const oldsize = size;
  size = n;

  // new capacity
  if (capacity == 0) { capacity = 1; }
  while (capacity < n) { capacity *= 2; }

  // new buffer (copied)
  try {

    T* newbuffer = (T*)malloc(capacity*sizeof(T));

    // copy
    for (size_t i = 0; i != oldsize; ++i) {
      new (newbuffer + i) T(*(buffer + i));
    }

    free(buffer)
    buffer = newbuffer;

  } catch(...) {
    free(newbuffer);
    throw;
  }
}

感觉不对吗?

我的意思是,我们甚至会处理由T的复制构造函数引发的可能异常!耶!

请注意我们遇到的微妙问题:如果抛出异常,我们更改了sizecapacity成员,但仍然使用旧版buffer

修复是显而易见的,当然:我们应该先改变缓冲区,然后再改变大小和容量。当然......

但它很难&#34;做对了。


我建议使用另一种方法:创建一个不可变的数组类(容量应该是不可变的,而不是其余的),并实现一个无异常的swap方法。

然后,您就可以实现&#34;类似交易的&#34;语义更容易。

答案 2 :(得分:2)

在添加元素时动态增长的数组称为动态数组,可增长数组,这是dynamic array的完整实现。

答案 3 :(得分:0)

在C和C ++中,数组表示法基本上只是短手指针数学。 所以在这个例子中。

    int fib [] = { 1, 1, 2, 3, 5, 8, 13};

此:

    int position5 = fib[5];

与说这句话是一样的:

    int position5 = int(char*(fib)) + (5 * sizeof(int));

所以基本上数组只是指针。

因此,如果你想自动分配,你需要编写一些包装函数来调用malloc()或new,(分别是C和C ++)。

虽然您可能会发现矢量是您正在寻找的......