创建20k数组时bad_alloc

时间:2014-04-07 06:56:44

标签: c++ arrays new-operator bad-alloc

我必须做某种项目而且我被困住了。我收到了bad_alloc错误。我检查了很多次代码,尝试谷歌一些解决方案,但仍然没有,这就是我写在这里的原因。事情是程序运行正常,但在任务管理器他的内存使用量增加到2GB(这是限制为我知道)然后它崩溃了。程序需要检查分配空间和复制变量的时间。这是代码的一部分:

class Table
{
    int *tablica;
    int size;

public:
Table()
    {
        tablica = NULL;
        size = 0;
    }

~Table()
    {
        delete tablica;
        size = 0;
    }

int *push_back(int val)
    {
        int *temp = new int[size];
        if(size % 10 == 0)
        {
            for(int i = 0; i < size; i++)
                temp[i] = tablica[i];
            tablica = new int[size + 10];
            for(int i = 0; i < size; i++)
                tablica[i] = temp[i];
        }
        tablica[size] = val;
        size++;
        delete []temp;
        return tablica;
    }

void test()
    {
            LONGLONG measure[100][6];
        LARGE_INTEGER performanceCountStart, performanceCountEnd;
        int cpy_tab [20000];

        for(int j = 0; j < 100; j++)
        {   
            for(int i = 0; i < 20000; i++)
                cpy_tab[i] = rand() % 10000 - 10000;

            performanceCountStart = startTimer(); 
            for(int i = 0; i < 500; i++)
                {
                    push_back(cpy_tab[i]);
                }
            performanceCountEnd = endTimer();
    measure[j][0] = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
            cout<<j<<"."<<measure[j][0]<<endl;

            delete []tablica;
            size = 0;

            performanceCountStart = startTimer(); 
            for(int i = 0; i < 2000; i++)
            {
                push_back(cpy_tab[i]);
            }
            performanceCountEnd = endTimer();
    measure[j][1] = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
            cout<<j<<"."<<measure[j][1]<<endl;

            delete []tablica;
            size = 0;


            performanceCountStart = startTimer(); 
            for(int i = 0; i < 4000; i++)
            {
                push_back(cpy_tab[i]);
            }
            performanceCountEnd = endTimer();
    measure[j][2] = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
            cout<<j<<"."<<measure[j][2]<<endl;

            delete []tablica;
            size = 0;


            performanceCountStart = startTimer(); 
            for(int i = 0; i < 8000; i++)
            {
                push_back(cpy_tab[i]);
            }
            performanceCountEnd = endTimer();
    measure[j][3] = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
            cout<<j<<"."<<measure[j][3]<<endl;

            delete []tablica;
            size = 0;


            performanceCountStart = startTimer(); 
            for(int i = 0; i < 14000; i++)
            {
                push_back(cpy_tab[i]);
            }
            performanceCountEnd = endTimer();
    measure[j][4] = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
            cout<<j<<"."<<measure[j][4]<<endl;

            delete []tablica;
            size = 0;

            performanceCountStart = startTimer(); 
            for(int i = 0; i < 20000; i++)
            {
                push_back(cpy_tab[i]);
            }
            performanceCountEnd = endTimer();
    measure[j][5] = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
            cout<<j<<"."<<measure[j][5]<<endl;

            delete []tablica;
            size = 0;
        }
    }

解决这个问题的任何想法对我来说都是值得的!

3 个答案:

答案 0 :(得分:2)

你肯定是在泄漏,并且在执行此操作时可能会破坏内存:

    int *temp = new int[size];
    if(size % 10 == 0)
    {
        for(int i = 0; i < size; i++)
            temp[i] = tablica[i];
        // Should free tablica here 
        tablica = new int[size + 10];
        for(int i = 0; i < size; i++)
            tablica[i] = temp[i];
    }

首先,您分配一个临时(即使您不需要),这是size元素,然后您分配一个size+10元素数组,该数组未被释放。

我建议您使用第二个变量来记录容量,并在每次容量时将容量加倍。这样,您不需要2000个分配来将阵列增长到20000个元素,但需要15个重新分配(和副本)。

答案 1 :(得分:1)

您无法准确显示您如何使用Table课程,但您可能会破坏堆。

test()函数反复将数据推送到tablica,然后在进行另一轮推送之前执行delete [] tablica

但是,当test()函数最后一次删除tablica时,它不会将poitner设置为NULL,而Table desctuctor如下所示:

~Table()
{
    delete tablica;
    size = 0;
}

因此它将继续删除该指针再次导致堆被破坏。请注意,delete中的~Table()操作应为delete [] tablica;

另请注意,在tablicapush_back()和dtor函数中管理test()指针会造成混乱。

答案 2 :(得分:1)

因为你正在泄漏tablica内存。 前

tablica = new int[size + 10];

添加一行

delete []temp;

一切都会好的。

在每次调用push_back时,你都会在temp中分配内存并删除它。而是在条件下分配内存并释放内部。