我有一个指向对象指针数组的指针,需要调整数组的大小。我确实意识到这是使用 vector 的最佳时机,但我不允许这样做。我的代码有效,但我没有完全遵循我所写的内容,担心我可能造成了内存泄漏:
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 = 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
不会泄漏(因为它在分配期间抛出,即没有分配)。
当然,请确保您在析构函数中删除[]集
(可能还有指针,以防您的集拥有它们)。
关于c++ - 在没有内存泄漏的情况下调整指针数组的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34581784/