一、前言
动态存储分配函数头文件malloc.h(ANSI标准建议使用stdlib.h,但很多编译器可能不支持),提供许多函数来实现对内存区域的堆上内存进行管理,主要有:
void *malloc(unsigned int num_bytes);
void *realloc(void* mem_address,unsigned int newsize);
void *calloc (size_t nmemb, size_t size);
二、用法
1.malloc函数
分配参数给定的字节数的内存空间,如果理解成返回指针的话,则指针类型需要人为定义。
例如:
int * p =null;
p= (int *) malloc(sizeof(int) * 10);
上述语句事实上是从堆中动态分配了40个字节的内存空间(按照int 是4个字节计算,即10个int的大小),p返回这一段空间的首地址,当然如果函数执行失败则返回null。此处得到的内存空间可使用函数memset进行初始化:
memset(p , 0 , sizeof(int)*10);
测试代码:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
int main(int argc , char* argv[])
{
int * p= NULL;
p = (int *) malloc( sizeof(int) * 10 );
memset(p, 0, sizeof(int) * 10 );
int a;
int i;
for(i = 0;i < 10;i++)
{
a = *(p+i);
printf("a = %d\r\n",a);
}
free(p);
return 0;
}
2.calloc函数
和malloc用法类似,第二个参数表示要分配的字节单元大小,第一个参数表示要分配多少个这样的字节单元,例如:p=(int *) calloc(10 , sizeof(int));是分配10乘sizeof(int)个字节即40个字节的空间,与malloc不同的是,动态分配完内存后,自动初始化该内存空间为零。当然如果执行成功返回指针首地址,执行不成功返回NULL。
测试代码:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
int main(int argc , char* argv[])
{
int * p= NULL;
//p = (int *) malloc( sizeof(int) * 10 );
//memset(p, 0, sizeof(int) * 10 );
p = (int *)calloc(10, sizeof(int));
//不需要memset进行初始化
int a;
int i;
for(i = 0;i < 10;i++)
{
a = *(p+i);
printf("a = %d\r\n",a);
}
free(p);
return 0;
}
3.realloc函数
例如:p=realloc(p,n);
第一个参数是指向堆内动态分配的内存,第二个参数表示重新分配的大小(当该参数为0时,返回NULL,并不代表指针被释放),事实上该函数主要用来扩大动态分配区域,即当第二个参数n大于第一个参数p指向的动态内存大小,这个时候,将重新申请一个大小为n的空间,而之前的空间归还给堆。
测试代码:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
int main(int argc , char* argv[])
{
int * p= NULL;
int * q= NULL;
p = (int *)malloc (sizeof (int) * 5);
q = p ;//这种做法事实上存在安全隐患
printf("before realloc.\r\n");
printf("p=%p q=%p\t\n",p,q);
p = (int *)realloc(p, sizeof(int) * 10);
printf("after realloc.\r\n");
printf("p=%p q=%p\r\n",p,q);
free(p);
free(q);
return 0;
}
注:代码注释中所说的安全隐患参考:http://blog.csdn.net/snlying/article/details/4005238