繁体   English   中英

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

[英]I need to resize an array of pointers

可以说我想调整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命令来摆脱旧数组吗? 或以某种方式删除数组而不触发每个成员的解构函数?

使用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;
};

但这仍然是非常脆弱的代码。

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

使用名为astd::vector ,resize调用看起来像

a.resize( newSize )

与DIY解决方案相反,当newSize较大时,矢量的那些多余元素将为空(这比将它们保留为不确定的值要安全一些)。

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

对于它的价值而言,您要尝试做的并不是一件坏事,有时候它是有道理的,但是newdelete (或new[]delete[]提供的接口根本不支持它。 )。 正如其他人所说, 被支撑mallocfree ,和realloc (需要提醒的是realloc将复制上重新分配的指针值,但不能保证在新区域的指针被初始化为有用的东西,比如NULL ) 。

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

就其价值而言,原始STL并未使用new[]delete[]来实现std::vector<T> 通常,操作系统提供的内存远远超出您的要求。 举例来说,如果我尝试malloc 16个字节,我回来了块很可能是1024个字节。 我可以用它来存储四个32位整数。 当我空间不足时,我可能会要求32个字节,并获得另一个1024字节的块,我可以将我的四个整数复制到该块中。 但是,当原始块实际上足够大以至于开始时,为什么还要麻烦索要一个新块来容纳我的整数呢? 不幸的是, new[]delete[]没有提供一种方式来表示“给我一个至少这么大的块,顺便说一下,这里的块可能已经足够大了”。 realloc某种功能。 Facebook Folly包含一个不使用new[]delete[] 类似std::vector的容器 (请注意,它也不使用realloc ,因为它通常不适用于对象容器;而是使用malloc以及非标准函数malloc_usable_size ), Firefox便以类似的方式来管理内存。

即使这样,我也不鼓励尝试变得棘手。 std::vector有很多满意的用户。

我认为在删除之前使数组中的所有元素都指向NULL应该可以完成这项工作。 但是,如果可以使用STL,则std :: vector将使您的生活更加轻松(如Alf建议的:P)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM