2016-12-27 61 views
1

我使用的代碼塊,我的代碼如下:的malloc沒有返回NULL,但索引數組給分段錯誤

分配陣列T:

long long TAILLE_MAX= 5000000000000; 
long long *T= malloc(sizeof(long long)*TAILLE_MAX); 

然後我想用的一部分該陣列的每個時間和下降值填充:

long long step= 5; 
for(long long TAILLE=500000000; TAILLE<=TAILLE_MAX; TAILLE*=step){ 
    if(step==2) step=5; 
    else step= 2; 

    for(long long n=0; n<TAILLE; n++) T[n]= TAILLE-n; 
    // rest of code (which is not reached) ... 

問題是在此循環:

for(long long n=0; n<TAILLE; n++) T[n]= TAILLE-n; 

它給分段故障,並且當我使用的調試器來分析我發現,它給出了錯誤,每次當n達到121197052必須被包含在陣列中的問題,

我認爲,它是一種與堆大小,但經t問題是由malloc分配,並沒有返回NULL,

我試圖通過將此鏈接器,來增加堆的大小:-Wl,--stack,568435456 ,但同樣的錯誤,

奇怪的是我試圖分配一個小於012的值但是malloc返回NULL !!!!它如何分配一個很大的尺寸,並返回NULL以減小尺寸!

我有Windows 7旗艦版64位,4Gb內存,Intel Core Duo 2.80GHz。

在此先感謝您的任何建議。

編輯: 關於持有這個問題:我不是在尋找調試程序!一點也不!我正在詢問其中的各種指令的行爲,如malloc,內存分配...,我不需要爲我的程序提供解決方案我正在尋找有關以上幾點對其他成員有用的信息,即使是標題顯示我在詢問某事的行爲。

+1

這是內存 – StoryTeller

+2

淫穢金額爲64位編譯過?即使64位機器,我的MSVC 15.0是32位。什麼是您可以傳遞給'malloc'的最大值?我懷疑你的「long long」正在被截斷。 –

+1

您通過codeblock IDE使用的編譯器是否創建64位輸出? Malloc將size_t作爲大小參數。在32位系統上,您要求的40,000,000,000,000字節的大小遠遠超過32位限制。 – Gerhardh

回答

3

malloc需要size_t的說法。

在MSVC 15.0 sizeof(long long)是8,sizeof(size_t)是4.較小的值失敗,因爲數量正確但內存不足。由於數字被截斷並且所分配的內存被分配,所以較大的值似乎會通過,但是當您爲想象中的內存編制索引時,它超出了實際內存的範圍。

使用MSVC,允許的默認內存約爲1.9 GB,包括靜態或動態的所有內容。

+0

在這種情況下,不應該MSVC給出警告,因爲64位的TAILLE_MAX的long long被截斷爲32位? –

+0

你不能'malloc'超過〜4GiBin在Windows?即使在Win64上?? – Olaf

+0

@Paul Ogilvie確實如此,*「警告C4244:'功能':從'__int64'轉換爲'size_t',可能會丟失數據」*。 –

1

它是操作系統和計算機特定的。在Linux上,它被稱爲memory overcommitment(這是一個錯誤的特性,使系統始終能夠成功請求mallocmmap,即使是一個淫穢的大小),我通常禁用它。

但是,有一點常識應該會讓你感到震驚。您需要64位的字,即8個字節。那將意味着40 * 10 字節。一個技嘉的字節數是10 字節(如果你想得到兩個冪的話,多一點),而你的筆記本電腦可能只有其中的幾個(可能在2016年底最多16GB)。您正在申請40TB(即40000G)的RAM(更確切地說是virtual address space,由RAM備份):即使是非常昂貴的計算機(例如花費100萬歐元或美元)也沒有那麼多的RAM(可通過單核),並簡單地調零內存可能需要幾小時的CPU時間。

實際上,您需要時可以更好地分配內存並使其增長(使用realloc)。所以代碼,而不是:

size_t size = 1000; 
long long *T = malloc(size*sizeof(long long)); 
if (!T) { perror("malloc"); exit(EXIT_FAILURE); }; 

(你總是對證的malloc失敗)

在以後的某個點(例如,當讀陣列),你可能會覺得有必要增加數組;一般的建議是(啓發式)幾何增長的大小:

size_t newsize = 4*size/3 + 10; 
T = realloc(T, newsize*sizeof(long long)); 
if (!T) { perror("realloc"); exit(EXIT_FAILURE); }; 
+0

非常有用的感謝,但我不明白爲什麼malloc沒有返回NULL而不是分配另一個大小! –

+2

這是某些操作系統的[錯誤]功能。 –

+0

謝謝(y),這兩個回覆很有用 –