我需要调整指针数组的大小

时间:2012-11-28 23:18:53

标签: c++

假设我想调整一个int指针数组,我有一个看起来像这样的函数

    template<typename T>
static void Resize(T* arr, UINT oldsize, UINT newsize) {
    T* ret = new T [newsize];
    memcpy(ret, arr, sizeof(arr[0]) * oldsize);
    delete[] arr;   
    arr = ret;
};

当我尝试调整使用“new”关键字创建的元素数组时(即使类中的数据本身是POD),问题就开始了,因为delete []会触发它们的解构函数然后离开新数组指向不再存在的对象。所以..即使对象是用“new”创建的,我只能使用free命令摆脱旧数组?或以某种方式删除数组而不触发每个成员的解构函数?

3 个答案:

答案 0 :(得分:4)

使用std::vector


编辑:根据大众需求,解释为什么OP的代码不起作用

代码:

template<typename T>
static void Resize(T* arr, UINT oldsize, UINT newsize) {
    T* ret = new T [newsize];
    memcpy(ret, arr, sizeof(arr[0]) * oldsize);
    delete[] arr;   
    arr = ret;
};

这里arr是一个按值传递的指针。最后分配给arr只会更新实际参数的本地副本。所以在这之后,实际的参数,在调用代码中,指向一个已经delete d的数组,这是一个非常灾难性的结果!

通过引用引用

,可以获得某种程度的救援
template<typename T>
static void Resize(T*& arr, UINT oldsize, UINT newsize) {
    T* ret = new T [newsize];
    memcpy(ret, arr, sizeof(arr[0]) * oldsize);
    delete[] arr;   
    arr = ret;
};

但这仍然是相当脆弱的代码。

例如,调用者需要跟踪数组大小。

如果std::vector名为a,则调整大小调用将显示为

a.resize( newSize )

与DIY解决方案相比,当newSize更大时,矢量的那些额外元素是无效的(这比将它们作为不确定的值更安全一些)。

std::vector可以像原始数组一样编入索引。有关如何使用它的更多详细信息,请参阅 C ++教科书。如果你还没有C ++教科书,那就得到一个:对于大多数人来说,从网上学习文章和Q / A来学习C ++是一个不切实际的主张。

答案 1 :(得分:2)

对于它的价值,你要做的事情并不是一件非常糟糕的事情,而且有时它是有意义的,但new和{{1}提供的界面根本不支持它(或deletenew[])。正如其他人所说,delete[]mallocfree支持 (需要注意realloc将复制指针值重新分配,但不保证新区域中的指针被初始化为任何有用的东西,如realloc)。

所以,不用多说,几乎每个人都能使用的最简单的答案是使用NULL而不是试图自己管理内存。向量具有调整大小的能力,当它执行时,它将复制需要复制的内容。存在std::vector<int>以提供“可调整大小的数组”并为您管理内存。实际上,如果你想要一个指针容器,你最好使用std::vector / std::vector<std::unique_ptr<T>>(在C ++ 11中)或来自Boost Pointer Container的东西。

对于它的价值,原始STL没有使用std::vector<std::shared_ptr<T>>new[]来实现delete[]。通常,操作系统提供的内存远远超出您的要求。例如,如果我尝试std::vector<T> 16个字节,我回来的块可能是1024个字节。我可以使用它来存储四个32位整数。当我用完空间时,我可能要求32个字节,并得到一个1024字节的不同块,我可以将我的四个整数复制到。但是,当原始块实际上足够大以至于开始时,为什么要经历要求新块来保持整数的麻烦?不幸的是,mallocnew[]没有提供一种方式来说“给我一个至少这么大的块,顺便说一句,这里的块可能已经够大了。” delete[]有点。不使用reallocnew[]的{​​{3}}(请注意,它也不使用delete[],因为它通常不适用于对象容器;相反,它使用realloc和非标准函数malloc)和Facebook Folly includes a std::vector-like container以类似的方式管理内存。

即便如此,我也不鼓励尝试变得棘手。 malloc_usable_size有很多满意的用户。

答案 2 :(得分:1)

我认为在删除之前使数组中的所有元素都指向NULL应该完成这项工作。但是如果你可以使用STL那么std :: vector会让你的生活更轻松(正如Alf所说:P)。