Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2835497
  • 博文数量: 523
  • 博客积分: 11908
  • 博客等级: 上将
  • 技术积分: 5475
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-03 15:50
文章分类

全部博文(523)

文章存档

2019年(3)

2013年(4)

2012年(71)

2011年(78)

2010年(57)

2009年(310)

分类: C/C++

2009-09-13 22:54:06

malloc calloc

 malloc

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

函数描述: 分配长度为num_bytes字节的内存块

入口参数: num_bytes    内存块的大小(单位为字节)

出口参数: 无(或为空)

返回值:    如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL
函数说明    不再使用时一定要记得释放,调用函数free

使用示例:

  char *pTemp = NULL;

  pTemp = (char *)malloc(10 * sizeof(char));

个人理解:

[1]申请空间大小时,利用sizeof做出计算,这样保证会分配正确数量的内存空间;

[2]malloc返回的内存是没有被初始化的,所以可能包含着任何的随机垃圾,应该在其后马上调用memset函数进行初始化为0的操作;

 

calloc

函数原型: void *calloc(size_t nelem, size_t elsize);

函数描述: 分配指定长度的内存空间

入口参数: nelem    元素的个数(如为10char申请空间,则为10

               elsize     元素所占用的字节(如为char申请,则为sizeof(char)

出口参数: 无(或为空)

返回值:    如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL
函数说明    不再使用时一定要记得释放,调用函数free

使用示例:

char *str = NULL;

str = calloc(10, sizeof(char));

个人理解:

[1]calloc实际上也只能算作是malloc的一种简单的封装;

[2]它会自动的把动态分配的内存进行清0操作,并且保证了分配数量的正确,所以建议使用。

 

其他说明:

进程对动态内存的分配请求被认为是不紧迫的。例如,当进程的可执行文件被装入时,进程并不一定立即对所有的代码进行访问。

类似地,当进程调用malloc() 请求动态内存时,并不意味着进程很快就会访问所有获得的内存。

因此一般来说,内核总是尽量推迟给用户态进程动态分配内存。

这里只是简单的做个说明……

 

malloc()函数: void *mallocsize_t size) 其中的size即为所用分配的内存空间的大小。

malloc函数有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数的时候,它将沿着连接表寻找一个大到足以满足用户请求所需要的内存块。

calloc()函数:void *callocsize_t numElements,size_t sizeOfElement); 其中numElements为分配的元素的个数,而sizeOfElement即为每个元素的大小了。这样,这两个数的乘积即为要分配的空间的大小了。

如果函数的调用成功,则malloc()和calloc()这两个函数返回的都将为分配的内存空间的首地址。

函数malloc()和函数calloc()的主要区别

malloc()不能初始 化所分配的内存空间,calloc()能。

如果由malloc()函数分配的内存空间原来没有被使用过,则其中的每一位可能都是0;反之,如果这部分内存曾经被分配 ,则其中可能遗留有各种各样的数据。也就是说,使用malloc()函数的程序开始时(内存空间还没有被重新分配)能正常进行,但经过一段时间(内存空 间还已经被重新分配)可能会出现问题。
    
函数calloc()会将所分配的内存空间中的每一位都初始化为零, 就是说,如果你是为字符类型或整数类型的元素分配内存,那麽这些元素将保证会被初始化为0;如果你是为指针类型的元素分配内存,那麽这些元素通常会被初始 化为空指针;如果你为实型数据分配内存,则这些元素会被初始化为浮点型的零。

   
另外,calloc返回的是一组对象的数组,而malloc返回的是一个对象。使用calloc表明是要使用一个数组。

关于函数使用需要注意的一些地方:
A
、申请了内存空间后,必须检查是否分配成功。

B
、当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。

C
、这两个函数应该是配对。如果申请后不释放就是内存泄露;如果无故释放那就是什么也没有做。释放只能一次,如果释放两次及两次以上会

出现错误(释放空指针例外,释放空指针其实也等于啥也没做,所以释放空指针释放多少次都没有问题)。

D
、虽然malloc()函数的类型是(void *),任何类型的指针都可以转换成(void *),但是最好还是在前面进行强制类型转换,因为这样可以躲过一 些编译器的检查。

 

 

malloc 定义为: void *malloc(unsigned int)

 

C使用void 服务于两个目的:

 

(1) 在函数定义中作为一种类型时,void 表示函数没有返回值。

 

(2) 用作指针定义时,void 定义一个通用指针(可以指向任何数据类型)。

 

函数malloc只有一个自变量:分配的字节数。如果malloc用光了内存,将返回一个空指针(可指向任意数据类型)。下面的一段代码为自定义数据结构person申请内存。

 

struct person...{

    char name[30];

    char addr[30];

    int age;

    float height;

}

 

struct person *ptr = malloc(sizeof(struct person));

if( ptr == NULL )...{

    fprintf( stderr, " Out of memory! ");

    exit(8);

}

 

 

malloc 函数为变量分配存储空间,然后返回指针,它用于在一个称为堆栈(heap)的内存空间里创建新实体。堆栈的大小虽然很大,但毕竟有限。malloc 用完内存后将返回NULL 指针。好的程序方法应告诉你检查每个malloc 调用的返回值(如上面代码中的if 语句部分),以确保真的得到了内存。

 

free 函数

 

在处理结束之后,使用free 函数释放内存。下面的一段代码用malloc 得到内存并释放它:

 

const int DATA_SIZE =(16*1024); /* apply for 16KB */

 

void copy( )

{

    char *data_buffer;

    data_buffer = malloc(DATA_SIZE);

 

    /*

     *    Use the data buffer to copy a file.

    */

 

    free(data_buffer);

    data_buffer = NULL:

}

使用free的一般形式是:

 

free (pointer);

 

pointer = NULL;

 

注意:不一定非要把指针设为NULL,但设为NULL可以阻止使用释放后的内存。调用free后使用指针,将有可能发生一个类似于数组下标超界的错误,因为你使用的是属于别的程序的内存空间,这可能会得到意想不到的结果,甚至使程序崩溃。

 

 

 

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