堆溢出影响其他程序

时间:2017-06-07 04:31:38

标签: c malloc heap

我试图为malloc创建一个返回NULL指针的条件。在下面的程序中,虽然我可以看到malloc返回NULL,但一旦程序被强制终止,我看到所有其他程序变慢,最后我不得不重启系统。所以我的问题是堆的内存是否与其他程序共享?如果没有,其他程序不应该受到影响。 OS是否在执行时没有分配一定量的内存?我正在使用Windows 10,Mingw。

#include <stdio.h>
#include <malloc.h>

void mallocInFunction(void)
{
    int *ptr=malloc(500);
    if(ptr==NULL)
    {
        printf("Memory Could not be allocated\n");
    }
    else
    {
        printf("Allocated memory successfully\n");
    }
}


int main (void)
{
    while(1)
    {
        mallocInFunction();
    }

    return(0);
}

4 个答案:

答案 0 :(得分:3)

  

...堆的内存是否与其他程序共享?

嗯,C标准并不完全需要,但在任务切换,多用户和多线程操作系统的上下文中,当然< / em>内存在进程之间共享! C标准不需要任何,但这都是很常见的东西:

  • 对于经常执行的代码,CPU缓存内存往往是首选,尽管这可能会被相当多的交换掉;可能会也可能不会交换到
  • 任务切换导致寄存器被交换到其他形式的存储器;可能会也可能不会交换到
  • 整个页面与磁盘交换,以便当您的操作系统从程序和其他程序执行开关时,其他程序可以使用它们,并且当您的程序再次执行时< em>以及其他原因。这可能涉及也可能不涉及操纵

FWIW,你指的是有allocated storage duration的记忆。最好避免使用 heap stack 之类的术语,因为它们实际上毫无意义。您所指的内存位于硅芯片上,无论它是使用还是堆栈

  

......操作系统在执行时是否没有分配一定数量的内存?

说到芯片和执行,你的操作系统可能只能控制一个处理器(一个硅芯片,其中包含一些逻辑电路和存储器,其中包括我确定)执行许多程序!总结一下这篇文章,是的,您的程序很可能与其他程序共享这些芯片

在切线上,我不认为 heap overflow 意味着你的意思。

答案 1 :(得分:3)

  

所以我的问题是堆的内存是否与其他程序共享?

物理内存(RAM)是所有进程共享的资源。操作系统决定分配给每个进程多少RAM,并随着时间的推移进行调整。

  

如果没有,其他程序不应该受到影响。 OS是否在执行时没有分配一定量的内存?

在程序开始执行时,操作系统不知道程序需要多少内存。相反,它会在发生时处理分配。除非另有配置,否则它通常会尽一切可能使程序的分配成功,因为可能是因为程序正在做它正在做的事情并且操作系统赢得了胜利。试着再次猜测它。

答案 2 :(得分:1)

你的问题无法用C语言来回答。对于C,没有进程,......

但是可以在操作系统的上下文中回答这个问题。甚至有点普遍,因为许多现代多任务操作系统都做类似的事情。

鉴于现代多任务操作系统,它将为每个进程使用虚拟地址空间。操作系统管理固定大小的物理RAM并将其划分为页面,当进程需要内存时,这些页面映射进入进程的虚拟地址空间(通常使用与物理地址不同的虚拟地址) )。因此,当操作系统本身和正在运行的进程声明所有内存页时,操作系统通常会将一些未处于活动状态的页面保存到交换区域中的磁盘,以便将此页面作为新页面提供给下一个请求过程的页面。但是当原始页面触及时(通常是free()的情况,请参见下文),必须先从磁盘再次加载,但要为此设置一个空闲页面, 另一个页面必须保存到交换空间。

就像所有磁盘I / O一样,这很慢,这可能就是你在这里看到的。

现在要完全理解这一点:malloc()做了什么?它通常从操作系统请求增加自己进程的内存(如果需要,操作系统通过映射另一个页面来执行此操作),并通过在那里写一些有关所请求内存块的信息来使用这个新内存(所以free()可以在以后正常工作)并最终返回一个指针,该指针可以自由地用于该程序。 free()使用malloc()编写的信息,对其进行修改以指示此块再次空闲,并且通常无法将任何内存返回给操作系统,因为还有其他信息malloc() d阻止同一页面。它会在可能的情况下返回内存,但在大量使用动态分配的典型情况下,这是例外。

因此,您的问题的答案是:是的,RAM是共享的,因为只有一组物理RAM。操作系统尽其所能隐藏这一事实并虚拟化 RAM,但如果一个进程消耗了所有内容,那么这将产生明显的效果。

答案 3 :(得分:1)

malloc()不是系统调用,而是libc库函数。因此,当程序要求通过malloc()分配内存时,系统调用brk()/ sbrk()或mmap()分配页面,更多细节here

请记住,你得到的内存本质上都是虚拟的,这意味着如果你有3GB的物理内存,你实际上可以分配几乎无限的内存。那么这是怎么回事?这通过名为&#39; paging&#39;的概念发生,其中系统存储和检索从辅助存储器(HDD / SDD)到主存储器(RAM)的数据,更多细节here

所以有了这个理论,内存通常非常罕见但是上面的程序正在检查系统限制,这可能发生。这很好地解释了here

现在,为什么其他程序会被绞死或缓慢?因为它们都共享相同的操作系统,系统正在匮乏资源。事实上,系统将崩溃并重新启动。

希望这有帮助吗?