2016-09-27 108 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