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