2016-09-27 41 views
0

在我的C程序中,根據用戶的輸入,將爲給定的模擬分配內存。我面臨的最初問題是用戶可以要求分配一個龐大的數字,但malloc()永遠不會失敗,直到內存不足,程序崩潰。如何檢查malloc()是否佔用內存

我調查了這個背後的邏輯,現在對我有意義,參見[1] [2]。此處給出的可能解決方法「SIGKILL while allocating memory in C++」建議將overcommit_memory設置爲/proc/sys/vm/overcommit_memory,從0到2.

從一方解決了問題。但由於我使用-fsanitize=address,因此我從消毒劑中得到錯誤。

有沒有更好的解決方案呢?

+2

如果用戶給出的值'X'作爲輸入,你知道* *多少字節,這將導致你的程序分配。你可以很容易地將'X'的值限制爲不會耗盡系統的東西。所以如果用戶輸入一個很大的值,告訴用戶它很大,然後再次詢問這個值。 –

+1

此外,你*確實知道['malloc'](http://en.cppreference.com/w/c/memory/malloc)在分配內存失敗時返回NULL。你也可以很容易地檢查它,而不是試圖解引用空指針。 –

+0

請提供一個最小,完整和可驗證的示例(http://stackoverflow.com/help/mcve) – stenliis

回答

0

我想叮噹AddressSanitizer失敗,因爲有一個合法的泄漏。所以,我的回答會忽略:

替代方案:

  1. 禁用過量使用的行爲,因爲你已經想通了:這會影響到其他進程,並要求根。
  2. 在禁用了oom殺手的Docker鏡像中運行應用程序:該程序不影響其他進程,但需要root用戶來安裝docker(儘管這是我最喜歡的解決方案)。
  3. 在malloc之後寫入:可能需要很長時間才能分配大量內存,並且由於其他正在運行的進程而導致進程仍然可能被殺死,但不需要root。
  4. 使用ulimit -v來限制根據機器的內存量:這也不需要root,但是你的進程可能會被終止。

代碼的第三個選擇(對於Linux):

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <signal.h> 
#include <setjmp.h> 

jmp_buf resume_malloc; 

void handle_malloc_error(int sig) 
{ 
    longjmp(resume_malloc, sig); 
} 

void *memalloc(size_t sz) { 
    void *p = 0; 
    int sig = setjmp(resume_malloc); 
    if (sig == 0) { 
     p = malloc(sz); 
     signal(SIGSEGV, &handle_malloc_error); 
     memset(p, 0, sz); 
    } else { 
     p = 0; 
    } 
    signal(SIGSEGV, SIG_DFL); 
    return p; 
} 

int main(int argc, char *argv[]) 
{ 
    size_t sz = 160L * 1024 * 1024 * 1024L; 
    void *p; 
    for (int i=0; i < 100; i++) { 
     printf("size: %lu\n", sz); 
     p = memalloc(sz); 
     if (p == 0) { 
     printf("out of memory\n"); 
     break; 
     } 
     sz *= 2; 
    } 
} 
+0

謝謝你的解釋!我非常喜歡使用跳遠的解決方案。我已經嘗試過,但我仍然面臨同樣的問題。所以這個過程被殺死了。關於消毒劑:沒有泄漏。我應該更好地解釋這一點。殺菌劑不能「初始化」,並且在我運行程序後,我得到「ReserveShadowMemoryRange失敗,同時嘗試映射0xdfff0001000字節。也許你正在使用ulimit -v」。根選項不適用於我的情況,因爲代碼將在其他計算機上使用。我希望有任何其他建議。 – omid

+0

還有一點要注意,當overcommit_memory爲0時,地址清理工作正常 – omid

+0

因此,看起來其他進程正在嘗試寫入實際上不可用的內存,並且正在由OOM殺手選擇要殺死的進程。如果是這樣你需要第一個或第二個解決方案。 – olivecoder