zoukankan      html  css  js  c++  java
  • C中malloc的使用

    malloc函数 
    原型:extern void *malloc(unsigned int num_bytes);

    用法:#include <malloc.h>

    功能:分配长度为num_bytes字节的内存块

    说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
    当内存不再使用时,应使用free()函数将内存块释放。

    举例:
    // malloc.c

    #include <syslib.h>//此处在VC6.0上调试有问题,最好改成#include <stdio.h>
    #include <malloc.h>
    main()
    {
    char *p;

    clrscr(); // clear screen
    p=(char *)malloc(100);
    if(p)
    printf("Memory Allocated at: %x",p);
    else
    printf("Not Enough Memory! ");
    free(p);

    getchar();
    return 0;
    }

    函数声明(函数原型): 
    void *malloc(int size); 
    说明:malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。 
    从函数声明上可以看出。malloc 和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。比如: 
    int *p; 
    p = new int; //返回类型为int* 类型(整数型指针),分配大小为 sizeof(int); 
    或: 
    int* parr; 
    parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100; 
    而 malloc 则必须由我们计算要字节数,并且在返回后强行转换为实际类型的指针。 
    int* p; 
    p = (int *) malloc (sizeof(int)); 
    第一、malloc 函数返回的是 void * 类型,如果你写成:p = malloc (sizeof(int)); 则程序无法通过编译,报错:“不能将 void* 赋值给 int * 类型变量”。所以必须通过 (int *) 来将强制转换。 
    第二、函数的实参为 sizeof(int) ,用于指明一个整型数据需要的大小。如果你写成: 
    int* p = (int *) malloc (1); 
    代码也能通过编译,但事实上只分配了1个字节大小的内存空间,当你往里头存入一个整数,就会有3个字节无家可归,而直接“住进邻居家”!造成的结果是后面的内存中原有数据内容全部被清空。 
    malloc 也可以达到 new [] 的效果,申请出一段连续的内存,方法无非是指定你所需要内存大小。 
    比如想分配100个int类型的空间: 
    int* p = (int *) malloc ( sizeof(int) * 100 ); //分配可以放得下100个整数的内存空间。 
    另外有一点不能直接看出的区别是,malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。 
    除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。

    对其做一个特例补充
    char *ptr;
    if ((ptr = (char *)malloc(0)) == NULL) 
    puts("Got a null pointer");
    else
    puts("Got a valid pointer");
    此时得到的是Got a valid pointer。把0赋给maclloc能得到一个合法的指针。


    struct hostent *hp;

    //注意是sizeof( sturct hostent )而不是sizeof( sturct hostent* )
    //其中N代表你需要的sturct hostent类型数据的数量
    hp = ( struct hostent* ) malloc ( N * sizeof( sturct hostent ) );

    if ( !hp )      //建议要加上这个内存分配成功与否的检测
    {
           // 添加内存分配失败时的处理方法
    }


    new delete, free malloc

    首先应该知道malloc 和free是匹配的;new和delete是匹配的,他们不可以混淆。   

    malloc和new都申请空间,但是new是强类型的分配,会调用对象的构造函数初始化对象,而malloc仅分配内存空间但是不初始化。

    new   自适应类型,malloc需要强制转换new按类型进行分配,malloc需要指定内存大小对于对象来说free的确释放了对象的内存,但是不调用对象的析构函数。delete不仅释放对象的内存,并且调用对象的析构函数所以在对象中用free删除new创建的对象,内存就有可能泄露在delete内部仍调用了free .

    补充一点:new和malloc虽然都是申请内存,但申请的位置不同,new的内存从free store分配,而malloc的内存从heap分配(详情请看ISO14882的内存管理部分),free store和heap很相似,都是动态内存,但是位置不同,这就是为什么new出来的内存不能通过free来释放的原因。不过微软编译器并没有很好的执行标准,很有可能把free store和heap混淆了,因此,free有时也可以。

    再补充一点:delete时候不需要检查NULL

    delete   NULL;      是没有任何问题的,所以     

    if(p)     

    {                 

    delete   p;                 

    p   =   NULL;     

    }     

    还不如     

    delete   p;     

    p   =   NULL;

    而free(NULL)那就麻烦大了。

    第二种解释

    动态存储分配
    在数组一章中,曾介绍过数组的长度是预先定义好的,在整个程序中固定不变。C语言中不允许动态数组类型。
    例如:
    int n;
        scanf("%d",&n);
    int a[n];
    用变量表示长度,想对数组的大小作动态说明,这是错误的。但是在实际的编程中,往往会发生这种情况,即所需的内存空间取决于实际输入的数据,而无法预先确定。对于这种问题,用数组的办法很难解决。为了解决上述问题,C语言提供了一些内存管理函数,这些内存管理函数可以按需要动态地分配内存空间,也可把不再使用的空间回收待用,为有效地利用内存资源提供了手段。
    常用的内存管理函数有以下三个:
    1. 分配内存空间函数malloc
    调用形式:
      (类型说明符*)malloc(size)
    功能:在内存的动态存储区中分配一块长度为"size"字节的连续区域。函数的返回值为该区域的首地址。
    “类型说明符”表示把该区域用于何种数据类型。
    (类型说明符*)表示把返回值强制转换为该类型指针。
    “size”是一个无符号数。
    例如:
              pc=(char *)malloc(100);
    表示分配100个字节的内存空间,并强制转换为字符数组类型,函数的返回值为指向该字符数组的指针,把该指针赋予指针变量pc。
    2. 分配内存空间函数 calloc
    calloc 也用于分配内存空间。
    调用形式:
      (类型说明符*)calloc(n,size)
    功能:在内存动态存储区中分配n块长度为“size”字节的连续区域。函数的返回值为该区域的首地址。
    (类型说明符*)用于强制类型转换。
    calloc函数与malloc 函数的区别仅在于一次可以分配n块区域。
    例如:
         ps=(struet stu*)calloc(2,sizeof(struct stu));
    其中的sizeof(struct stu)是求stu的结构长度。因此该语句的意思是:按stu的长度分配2块连续区域,强制转换为stu类型,并把其首地址赋予指针变量ps。
    2. 释放内存空间函数free
    调用形式:
      free(void*ptr);
    功能:释放ptr所指向的一块内存空间,ptr是一个任意类型的指针变量,它指向被释放区域的首地址。被释放区应是由malloc或calloc函数所分配的区域。
    【例】分配一块区域,输入一个学生数据。
    main()
    {
        struct stu
        {
          int num;
          char *name;
          char sex;
          float score;
        }  *ps;
        ps=(struct stu*)malloc(sizeof(struct stu));
        ps->num=102;
        ps->name="Zhang ping";
        ps->sex='M';
        ps->score=62.5;
        printf("Number=%d Name=%s ",ps->num,ps->name);
        printf("Sex=%c Score=%f ",ps->sex,ps->score);
        free(ps);
    }

    本例中,定义了结构stu,定义了stu类型指针变量ps。然后分配一块stu大内存区,并把首地址赋予ps,使ps指向该区域。再以ps为指向结构的指针变量对各成员赋值,并用printf输出各成员值。最后用free函数释放ps指向的内存空间。整个程序包含了申请内存空间、使用内存空间、释放内存空间三个步骤,实现存储空间的动态分配。(转自网络)

  • 相关阅读:
    委托&指针函数&回调函数
    Unity animation笔记1
    hadoop源码编译
    protocbuf的安装
    学习hadoop不错的一些文章
    moven的安装
    在Linux上安装与配置Hadoop
    linux tar命令详解
    How to contribute to hadoop common
    Ubuntu下SVN的安装
  • 原文地址:https://www.cnblogs.com/lizhenli/p/3411219.html
Copyright © 2011-2022 走看看