c语言-malloc动态分配与自动分配

  • 简单说一下c语言中malloc函数的动态分配
    malloc函数在linux终端下,敲 man malloc 就可以看到手册中malloc函数的详细介绍。可是。。。手册都是英文的啊!对于英文不好的我,读起来还是挺生硬。。。
       void *malloc(size_t size);
       void free(void *ptr);
       void *calloc(size_t nmemb, size_t size);
       void *realloc(void *ptr, size_t size);
       void *reallocarray(void *ptr, size_t nmemb, size_t size);

以上这些函数呢,就是让程序猿来手动分配程序所需要的空间大小。函数用起来简单,重要的是理解,不然用了还是容易出错。所以下面主要写的是一些初步理解方面的,等到用得多了就能更有经验了。

与自动分配空间相比有下列一些区别:

  • 时间不同
    自动分配是编译器默认的类型(auto自动型),自动分配空间,自动回收空间。这一过程都是在编译时,编译器设定好的。而动态分配程序执行时,调用malloc等函数进行分配的。

  • 空间不同
    我们把c语言编译后的应用程序在内存中的占用,按地址高低顺序分为以下部分:
  1. 栈区(stack)-存放函数的参数值,局部变量的值等。
  2. 堆区(heap)-由程序猿分配释放,若程序猿不释放,程序结束时可能由由系统自动回收 。
  3. 全局区(static)-存放的是全局变量和静态变量,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 程序结束后由系统释放。
  4. 文字常量区-常量字符串就是放在这里的。程序结束后由系统释放。
  5. 代码区-存放函数体的二进制代码。

malloc函数分配的区域就是堆区,程序猿利用malloc函数在堆区分配一个指定大小的空间。
动态分配的好处是:自由度大,想什么时候分配就什么时候分配,分配大小也自己定,不用受编译器和系统的太多限制。堆的空间还大。
但动态分配最致命的就是:内存泄露-指程序中动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

自由的同时带来了麻烦!如果把自动分配比作孩子,内存空间比作生活的开销,系统和编译器就是父母。父母每月给孩子固定的money,省下来的money孩子自己偷偷买皮肤,没了父母给。而动态分配自己就是父母,只能自己替自己做主,每一笔开销都要打量着。花完之后,一个free函数,花完的钱又回来了(要是真的就好了),不free或者free错误直接破产。

下面来个错误示范

void test1(int *p,int n)
{       
        p = malloc(n);
        if(p == NULL)
                exit(1);
}       

int main()
{       
        int num = 100;
        int *p = NULL;

        test1(p,num);
        free(p);
 
        return 0;
}

结果:

结果是空,什么也没有,也没有报任何错误。多么会钻空子的错误,main函数中free的p其实是main中的空指针,这两个函数中定义的都是局部变量,有作用域限制,这很简单的道理,但往往就会陷入这样的陷阱。free函数只释放之前调用 calloc、malloc 或 realloc 所分配的内存空间,对空指针不会进行任何操作,但也不会报错。
所以谨记:
* 成对使用,有一个malloc,就应该有一个free.
* 最好在同一调用层上使用这两个函数,不要像上面的错误示范一样。
* malloc分配的内存一定要初始化。free后的指针一定要设置为NULL。

以上就是初步的理解和使用。

猜你喜欢

转载自www.cnblogs.com/tansss/p/12488980.html