繁体   English   中英

调整指针数组的大小而不会导致内存泄漏

[英]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.

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