当前位置:C++技术网 > 资讯 > 函数内部分析:3 malloc函数内部执行过程分析

函数内部分析:3 malloc函数内部执行过程分析

更新时间:2015-06-23 19:55:26浏览次数:1+次

    malloc函数是内存分配函数,在C语言中使用最常见。而在C++语言中,则是使用new操作符完成内存的动态分配。不过,new操作符内部是通过调用malloc实现的。因此,要更加深入了解内存分配原理,需要对malloc函数深入剖析了。
    malloc函数有一个回滚机制,相当于数据库的混滚操作一样,也就是原子操作。通俗的讲,就是“要么将指定大小的字节数分配到位,要么一个也不分配”。也就是说,如果系统只有10可用的字节内存了,而请求数量有11个字节。程序先请求到了10,但是最后一个却得不到。这样的话,如果始终得不到最后的一个,程序就认为之前请求的10也就没有意义了。因此,先将请求到的10个字节的内存释放完后,抛出内存分配异常。所以,如果分配失败,大可不必担心已分配的内存会带来内存泄露或者其他的隐患。
    在malloc函数中,会创建一个临时的void*指针,用来接收分配到的内存的起始地址,然后返回给函数使用。分配的过程内部还是循环处理分配,直到分配成功或者执行了异常处理返回为止。文章《new的内部执行逻辑深入分析》中提到了new的内存分配是有一个循环执行的,而new的循环过程会执行malloc函数的。而malloc函数的内部也有一个循环的,分配失败则调用异常处理函数。只不过,malloc函数调用的内存分配函数则是系统的内存分配API函数。在Windows系统中,则是调用HeapAlloc函数来分配。可想而知,在Linux系统,当然也是调用Linux系统的内存分配API函数。
    系统API函数自然是需要系统的进程内存堆的入口指针的,而这个指针是一个全局变量。进程创建时就设置好了。分配内存的时候就将这个参数传入系统API来分配,而大小和分配模式,则有程序运行时传入。而分配模式和具体的系统有关,可以查阅系统API函数得知,在此就不列举了。系统API分配内存后返回内存指针,然后检测指针是否为空,同时检测异常处理标志位,看看是否设置了异常处理。如果没有设置,则直接返回空指针,宣告失败。如果设置了处理标志,则调用异常处理函数。
    malloc内部调用的和new中调用的异常处理函数是同一个,但是malloc是第一个执行的,new的异常则在malloc中的异常处理函数未执行才有机会执行。malloc内的异常处理优先级更高。
    通过上述分析,你可以很清楚的看到,使用new来分配内存和malloc来分配的效果是一样的,不过new分配起来效率变低了。因为new内部调用了malloc。但是new使用是操作符形式,更加方便,malloc使用起来是函数形式。
    在C语言中,你也就使用malloc,在C++中看情况选择new或者malloc。差别不大,只是习惯和具体需求问题了。