我正在編寫一個程序來對DNA序列進行一些分析。 一切工作正常,除了這件事情。 我想聲明一個大小爲m * n的二維數組,其中m和n是從輸入文件中讀取的。 現在的問題是,如果m和n變得太大。作爲一個例子,如果m = 200和n = 50000 那麼我在我聲明我的數組的線路上出現seg故障。在2D 2D陣列的情況下出現Seg故障
array[m][n];
任何想法如何克服這一點。我確實需要這樣一個數組,因爲我的整個邏輯取決於如何處理這個數組。
我正在編寫一個程序來對DNA序列進行一些分析。 一切工作正常,除了這件事情。 我想聲明一個大小爲m * n的二維數組,其中m和n是從輸入文件中讀取的。 現在的問題是,如果m和n變得太大。作爲一個例子,如果m = 200和n = 50000 那麼我在我聲明我的數組的線路上出現seg故障。在2D 2D陣列的情況下出現Seg故障
array[m][n];
任何想法如何克服這一點。我確實需要這樣一個數組,因爲我的整個邏輯取決於如何處理這個數組。
可能您的堆棧空間已用完。
你不能在堆上動態分配數組使用malloc
?
你可能想看看this答案如果你不知道該怎麼做。
嘿,謝謝。得到了提示.. –
+1爲正確的答案,但鏈接不好。不需要去迭代指針數組。只要'double(* array)[n] = malloc(double [m] [n]);'會的。 –
您可能會用完堆棧空間。
Windows實例爲每個線程提供1MB堆棧。假設數組包含整數,並且您正在堆棧上創建它,那麼您將創建一個40MB堆棧變量。
您應該改爲在堆上動態分配它。
不知道你正在使用的是什麼類型,但是對於下面的代碼我假設爲int。
不是這樣:
int array[200][50000];
試着這樣做:
int** array = (int**)malloc(200);
for (int i = 0; i < 200; i++)
{
array[i] = (int*)malloc(50000);
}
這將撥出 「堆」 內存,而不是 「堆棧」 內存。你要求超過300MB(如果你使用的是32位類型),所以你可能沒有那麼多的「堆棧」內存。
確保清理你用數組做用後:
for (int i = 0; i < 200; i++)
{
free(array[i]);
}
free(array);
隨意使用m和n,而不是我在上面使用的常量!我最初是用C++編寫的,並轉換爲C.我用C內存分配/釋放更加生鏽,但我相信我說得對。
Ahhh廢話,C不是C++。給我一分鐘編輯。 –
謝謝。 我們可以用相同的方式解引用數組嗎? 因爲如果我想要訪問數組[100] [500],那麼我可以像使用普通2D數組一樣使用數組[100] [500]? –
是的。一個int [] []祕密是一個int **。 :) –
數組(如果是本地)在堆棧中分配。對進程/線程的堆棧大小有一定的限制。如果堆棧過長,則會導致問題。
但是你可以使用malloc在堆中分配數組。典型的堆大小可能是4GB(根據操作系統/架構,這可能更多或更少)。檢查malloc的返回值以確保數組的內存被正確分配。
正如其他人所說,在堆棧上分配一個大的VLA(可變長度數組)不是一個好主意。與malloc
分配它:
double (*array)[n] = malloc(sizeof(double[m][n]));
,並有了與以前的對象,那就是編譯器完全知道如何解決單個元素array[i][j]
和分配仍然爲您提供了一個內存連續斑點。
只是不要忘記做
free(array);
在你的範圍的結束。
你可能對C/memory有更多的瞭解,所以請糾正我錯在哪裏。用他和m的值(200,50000),你的答案是要求連續300mb的內存塊,而我的答案是要求200個獨立的1.5mb塊。由於內存碎片,您是否更有可能獲得更小的塊? –
我不確定是否正確理解你的問題。在現代系統中,像這樣的大塊被「匿名映射」分配,即系統只在虛擬內存中保留一個地址範圍,並根據需要爲其分配物理頁面。釋放分配的所有影響時都沒有了。對於您的方法,系統可能會保留各個塊以便稍後重新使用它們。如果你重複一遍,你可能會增加很多碎片。您通過執行大量的分配來強調「malloc」系統的不必要,這樣所有的分配都會同時釋放。 –
你要求超過300兆字節(假設32位類型)...嘗試動態分配新的。 –