-3

我必须做一些项目,但我被困住了。我收到一个 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;
        }
    }

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

4

3 回答 3

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 次重新分配(和副本)。

于 2014-04-07T07:29:46.183 回答
1

Because you are leaking tablica memory. Before

tablica = new int[size + 10];

Add a line

delete []temp;

And everything would be fine.

More over in every call of push_back you are unnecessarily allocating memory in temp and deleting it. Instead allocate the memory and free inside if condition.

于 2014-04-07T07:41:30.403 回答
1

您没有确切显示您是如何使用Table该类的,但您可能正在破坏堆。

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

但是,当test()函数tablica最后一次删除时,它并没有将指针设置为NULL,并且Tabledesctuctor 看起来像:

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

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

另外,请注意,tablicapush_back(),test()和 dtor 函数管理指针会导致混乱的情况。

于 2014-04-07T07:35:38.367 回答