[英]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;
};
但这仍然是非常脆弱的代码。
例如,调用方需要跟踪数组大小。
使用名为a
的std::vector
,resize调用看起来像
a.resize( newSize )
与DIY解决方案相反,当newSize
较大时,矢量的那些多余元素将为空(这比将它们保留为不确定的值要安全一些)。
可以像原始数组一样索引std::vector
。 有关如何使用它的更多详细信息,请参见C ++教科书 。 如果您还没有C ++教科书,请阅读一本:对大多数人来说,从网上的文章和Q / A中学习C ++只是不切实际的主张。
对于它的价值而言,您要尝试做的并不是一件坏事,有时候它是有道理的,但是new
和delete
(或new[]
和delete[]
提供的接口根本不支持它。 )。 正如其他人所说, 在被支撑malloc
, free
,和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.