Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2675503
  • 博文数量: 877
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5921
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-05 12:25
个人简介

技术的乐趣在于分享,欢迎多多交流,多多沟通。

文章分类

全部博文(877)

文章存档

2021年(2)

2016年(20)

2015年(471)

2014年(358)

2013年(26)

分类: LINUX

2014-04-24 09:34:36


http://blog.csdn.net/andy_yf/article/details/7060670

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

用法:#include

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

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

举例:
// malloc.c

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

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

    getchar();
    return 0;
}

函数声明(函数原型): 
void *malloc(int size); 
说明:malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。

malloc与new的不同: 

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能得到一个合法的指针。

对结构体使用malloc操作:

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\nName=%s\n",ps->num,ps->name);
    printf("Sex=%c\nScore=%f\n",ps->sex,ps->score);
    free(ps);
}

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

C语言malloc的使用浅谈

参考文献:C_Free API文档

在c语言的编程中常常要对内存操作,而这对不少人来说是个不简单的问题。

最近在做作业的过程中常常看到在用到存储结构的地方常常有malloc的身影,我就在想到底什么时候什么地方该用到malloc 经过在百度和狗狗的一番搜搜之后在下的愚见总结如下:

一、使用malloc的情况

首先说明一下,由malloc动态申请的内存空间是堆式的内存空间。

而静态的内存的空间是栈式的。有关堆栈的知识请参考其他相关资料。

1.       大容量内存需求

网上说当我们需要的内存空间超过0.5兆的时候最好使用动态内存,也就是利用malloc来申请内存空间。可以这么认为,如果内存过大,就会不易管理,而malloc可以说事一个专业的内存管理者,但静态的则可以当成是一个业余的。毕竟术业有专攻。

2.       不确定内存需求

当我们需要的内存空间大小连我们自己也不知道的时候。为了不使内存空间的浪费。我们需要用到malloc函数。可以这样理解如果说静态的内存空间是一个铁盒子的话那么动态内存空间就可以看作是可伸缩的袋子,它的容量可以根据你所装物体的体积不同而定制。当然我们也可以利用静态内存,这样会有两种可能出现的结果,一是你所申请的空间不够用,程序异常。二是申请的内存过大,浪费。

我们来看在链表中情况,如果我们定义好了一个长度为十的链表之后想要在某个位置插入或删除一个节点。这个时候我们数组静态的话肯定会在数组数值的移动上花费有很大的开销。而利用malloc动态存储时就不会出现这样的情况。由于动态申请到存储空间不一定是连续的存储空间。所以当我们使用malloc申请空间时。计算机会在‘任意’可以申请到空间的地方给我们开辟需要的空间来供我们使用。新申请的空间与原来的空间只有通过指针想连接的关系物理上并一定有前后的关系。所以就不需要对原来的数据做移动操作。这样的系统开销就相对小了很多。相应的free的时候也是对“不相关”的空间进行操作。所以也不用对数据做移动操作。

3.       备注

二、如何科学使用malloc

1.       申请

calloc

语法:

 

  #include

  void *calloc( size_t num, size_t size );

功能: 函数返回一个指向num 数组空间,每一数组元素的大小为size。如果错误发生返回NULL。

 


      malloc 

 

  #include

  void *malloc( size_t size );

功能: 函数指向一个大小为size的空间,如果错误发生返回NULL。 存储空间的指针必须为堆,不能是栈。这样以便以后用函数释放空间。例如:

    typedef struct data_type {

      int age;

      char name[20];

    } data;

   

    data *bob;

    bob = (data*) malloc( sizeof(data) );

    if( bob != NULL ) {

      bob->age = 22;

      strcpy( bob->name, "Robert" );

      printf( "%s is %d years old\n", bob->name, bob->age );

    }

free( bob );

 

realloc

语法:

 

  #include

  void *realloc( void *ptr, size_t size );

功能: 函数将ptr 对象的储存空间改变为给定的大小size。 参数size可以是任意大小,大于或小于原尺寸都可以。 返回值是指向新空间的指针,如果错误发生返回NULL。

2.       释放

free

语法:

 

  #include

  void free( void *ptr );

功能: 函数释放指针ptr指向的空间,以供以后使用。指针ptr 必须由先前对, , 的调用返回。例如:

    typedef struct data_type {

      int age;

      char name[20];

    } data;

   

      data *willy;

    willy = (data*) malloc( sizeof(willy) );

    ...

free( willy );

阅读(598) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~