簡體   English   中英

cicle中的動態內存分配-C ++

[英]Dynamic memory allocation in a cicle - c++

在循環中動態分配內存的最佳方法是什么?

1.釋放每個循環的內存?

int *foo;
for(int i=1;i<10;i++)
{
    foo = new int [i];
    /*
    ...
    */
    delete foo;
 }

要么

2.釋放內存到底?

int *foo;
for(int i=1;i<10;i++)
{
    foo = new int [i];
    /*
    ...
    */
 }
 delete foo;

首先,當您使用new[]運算符時,需要將其與delete[]運算符進行匹配,因此您應該執行delete[] foo

其次,如果在循環后執行delete[] ,則只會釋放分配的最后一個內存,從而導致內存泄漏。

第三,您真的需要使用原始指針嗎? 您不能使用例如std::vector代替嗎?

選項1:多次分配/重新分配=效果不佳

for(int i=1;i<10;i++)
{
    foo = new int [i];
    /*
    ...
    */
    delete[] foo;
}

選項2:多次分配/一次重新分配=內存泄漏

int *foo;
for(int i=1;i<10;i++)
{
    foo = new int [i];
    /*
    ...
    */
}
delete[] foo;

選項3:一次分配/一次解除分配=如果需要動態內存,則確定

int *foo = new int [10];
for(int i=1;i<10;i++)
{
    /*
    ...
    */
}
delete[] foo;

選項4:避免動態分配/取消分配

for(int i=1;i<10;i++)
{
  int foo[ i ];
    /*
    ...
    */
}
  • 在第一個示例中,您有未定義的行為,需要使用delete[]來刪除由new []分配的數組

  • 在第二個示例中,同樣的問題,但是即使您修復了該問題,也將發生內存泄漏,因為僅會刪除最后分配的數組。


解:

  • 最好的方法是使用標准容器:

例如:

std::vector<int>
std::array<int, 10>
  • 或者,您仍然可以使用智能指針:

例:

for(int i=1; i<10; i++)
{
    auto foo = std::unique_ptr<int[]>(new int [i]);
    /*
    ...
    */
 }; 
  • 或者,如果您確實不能這樣做,請確保對new[]每次調用都與對delete[]的調用匹配

第一個示例更好,盡管您應該調用:

delete [] foo;

釋放整個塊。

您的第二個示例是內存泄漏。 原因如下:

在第一次迭代期間,將分配內存,並將foo設置為指向已分配緩沖區的開始。 第一次迭代之后的每個迭代都不會釋放在先前迭代中分配的內存。 而是將foo設置為指向新分配的緩沖區。 此后,不再有任何方法可以引用先前分配的緩沖區。

首先,使用new ,沒有很好的解決方案。 該參數每次在循環中都是一個新的std::vector ,而不是在循環外部,每次通過循環時都要重新resize

std::vector<int> foo;
for ( int i = 1; i < 10; ++ i ) {
    foo.resize( i );
    //  ...
}

for ( int i = 1; i < 10; ++ i ) {
    std::vector<int> foo( i );
    //  ...
}

如果您在循環中進行任何實際工作,則差異可能並不明顯,但是...

您可以使用reserve來改進第一個版本:

std::vector<int> foo;
foo.reserve( 10 );
for ( int i = 1; i < 10; ++ i ) {
    foo.resize( i );
    //  ...
}

如果循環的其余部分都很瑣碎,則可能會更快。 為此,如果最大大小已知並且不太大,則可以使用:

int foo[10];
for ( int i = 1; i < 10; ++ i ) {
    //  ...
}

在很多情況下,這是完全可以接受的,並且它將是最快的(盡管在大多數情況下,性能差異可以忽略不計,並且您將失去std::vector的優勢) ,包括優化未啟用時的邊界檢查)。

最好避免使用當前使用的向量。 但是,如果這純粹是為了學習,則建議您將每個指針(新的int [])存儲在數組中。 這樣做的原因(如果現在還不清楚)是因為您不斷在內存中分配一個新的指向數組的指針,然后通過在不調用delete []的情況下將新內存分配給相同的指針而丟失了對它的引用。

有了更好的設計,正如我之前提到的,您可以存儲此類指針的數組,例如* foo,然后可以清理析構函數〜Foo()中的內存。 只是一個主意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM