调整动态数组大小时内存泄漏

时间:2013-10-29 18:57:30

标签: c++ memory-management dynamic

这是我的代码:

template<class T> class Test 
{
    public:
    int Size = 0;
    int Length = 0;
T* Items; 

    Test() {}

~Test() 
    {  
    delete [] Items; 
    }

    void Append(const T& newItem) 
{
        if (Size + 1 >= Length)
    {   
        Length += 250;
            T* old = Items; 
        Items = new T[Length + 250]; 
            for (int i = 0; i < Size; i++) 
           Items[i] = old[i];
            delete [] old; 
        }

        Items[Size] = newItem;  
    Size++;
} 
};

Test<int> test;
for (int i = 0; i < 500000; i++)
   test.Append(i);

我用500000个整数填充动态数组,这个整数必须只需1-2Mb,但需要大约30Mb。如果我将初始大小设置为500000(即没有调整大小),则没有问题。增长值(250)似乎以某种方式影响内存,如果它更大(例如1000)则内存使用率相当低。怎么了?

2 个答案:

答案 0 :(得分:1)

通常,当您重新分配数组时,您不希望在最后一秒之前修改实际数组(以保持异常安全):

T* temp = new T[new_size]; 
// assume count is the previous size and count < new_size
std::copy(Items, Items + count, temp);
std::swap(temp, Items);
delete [] temp;

除此之外,代码中没有任何内容可以导致内存泄漏。

额外的大小可能是由于其他优化(被关闭)和/或调试符号被打开。你使用什么编译器选项(和什么编译器)?应该注意的是,额外的大小不一定是内存泄漏的指示。你是否在发现泄漏的调试器或内存分析器中运行它?

还应该注意std::vector为你完成所有这些。

答案 1 :(得分:1)

查看你的代码,你会比泄漏内存更容易发生段错误,因为在非NULL上调用deletedelete[],但之前已解除分配的指针是坏的事情。另外,我不相信这是你真正的代码,因为你发布的内容不会编译。

当你delete指针时,总是将其设置为NULL。初始化为NULL也是一种很好的做法。让我们修复你的代码,以确保我们不会在先前释放的指针上调用delete。另外,让我们将指针初始化为NULL。

您对内存的滥用可能源于以下几行代码:

Length += 250;
T* old = Items; 
Items = new T[Length + 250];

请注意,您将Length增加250,然后再分配长度+ 250个元素?让我们解决这个问题。

template<class T> 
class Test 
{
public:
    int Size;
    int Length;
    T* Items; 

    Test() : Size(0), Length(0), Items(NULL){}

    ~Test() {
       if (Items != NULL)
          delete [] Items; 
    }

    void Append(const T& newItem) 
    {
        if (Size + 1 >= Length)
        {   
           Length += 250;
           T* old = Items; 
           Items = new T[Length]; 
           for (int i = 0; i < Size; i++) 
              Items[i] = old[i];
           delete [] old;
           old = NULL;
        }

        Items[Size] = newItem;  
        Size++;
    } 
};

int main(){
    Test<int> test;
    for (int i = 0; i < 500000; i++)
       test.Append(i);
}