[英]resize an array of pointers without memory leak
我有一个指向对象的指针数组的指针,并且需要调整数组的大小。 我确实意识到这是使用向量的绝好时机,但是我不允许这样做。 我的代码可以工作,但是我不完全遵循我写的内容,并且担心我可能造成了内存泄漏:
void foo (DataSet &add_data)
{
if (sets == NULL)
{
sets = new DataSet*[1];
sets[0] = &add_data;
}
else
{
DataSet **transfer;
transfer = new DataSet*[num_of_sets];
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
transfer[i] = sets[i];
delete [] sets; // Free the array.
sets = new DataSet*[num_of_sets + 1]; // Create new sets
for (int i = 0; i < num_of_sets; i++) // Copy back
sets[i] = transfer[i];
sets[num_of_sets] = &add_data; // Add the new set
delete [] transfer;
transfer = NULL;
}
num_of_sets++;
}
为什么Visual Studio为以下情况引发异常:
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
*transfer[i] = *sets[i];
但不是:
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
transfer[i] = sets[i];
但是,这两个代码段都可以在linux中编译并正常运行。 此代码应复制指向对象的指针。 那是怎么回事:
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
transfer[i] = sets[i];
我是否需要担心以后是否要使用移除功能释放这些对象?
*transfer[i] = *sets[i];
不像其他示例(不带星号)那样复制地址,它尝试取消引用在这些地址上的DataSet
对象上transfer
和call operator=
的未初始化指针元素。
这是不确定的行为,这就是为什么它在变化的环境下似乎可以工作的原因。
您不需要分配两次,只需分配一次最终大小即可:
transfer = new DataSet*[num_of_sets + 1]; // Create new sets - final size
for (int i = 0; i < num_of_sets; i++) // Copy addresses?
transfer[i] = sets[i];
delete [] sets; // Free the array.
sets = transfer;
sets[num_of_sets] = &add_data; // Add the new set
// now no need to delete[] transfer
这样,您还将获得更好的异常安全性。 -在原始代码中,您在分配新数据之前删除了sets
-如果这将引发std::bad_alloc
,则不仅您的对象将变得不一致(具有悬挂的sets
ptr,因为在删除后您不为其分配null ),但分配给transfer
的内存也会泄漏。 如果您在delete[] sets
之前直接将transfer
分配为最终大小,则如果抛出该异常,则sets
将保持不变,并且transfer
不会泄漏(因为它在分配过程中被抛出,即未分配)。
当然,请确保您在析构函数中delete[] sets
(如果您的指针是指针的所有者,那么还可以包括它们)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.