浅谈“C语言动态内存管理:malloc/calloc/realloc/free”

1.malloc

  • 声明:
void *malloc(size_t size);
  • 作用:分配足够的内存给大小为size的对象,并返回指向所分配区域的第一个字节的指针,若内存不够,则返回NULL,并且 不对分配的空间进行初始化。(其中,指针的类型为void*,size_t代表的是unsigned int)
  • 举例说明:
int *number;
number = (int *)malloc(sizeof(int));//分配一个大小为sizeof(int)的存储空间,返回的指针需要强转成需要的类型
if (NULL == number)//判断调用是否成功,不成功就退出
{
    exit(0);
}
*number = 100;//内存里的内容没有被初始化,值不确定,此处需要初始化
free(number);//用完之后要free,释放内存
number = NULL;//防止出现野指针

注意:如果size是0,那么返回值不确定,取决于不同库的实现,但是返回值必定是不能引用的。
如果调用失败,则返回空指针。

2.calloc

  • 声明:
void* calloc (size_t num, size_t size);
  • 作用:为一个大小为num的数组分配内存,每个元素的大小是size,并且将每个元素初始化为0,同时返回指向所分配区域的第一个字节的指针。若内存不够,则返回NULL。
  • 举例说明:
int *number;
int i = 0;
number = (int *)calloc(3, sizeof(int));//分配一个大小为3*sizeof(int)的存储空间,
if (NULL == number)//判断调用是否成功,不成功就退出
{
    exit(0);
}
for (i; i<3; i++)
{
    printf(“address:%d number[%d] = %d\n”, &number[i], i, number[i]);//打印结果是0
}
free(number);//用完之后要free,释放内存
number = NULL;//防止出现野指针

注意:如果size是0,那么返回值不确定,取决于不同库的实现,但是返回值必定是不能引用的。
如果调用失败返回空指针。

3.realloc

  • 声明:
void* realloc (void* ptr, size_t size);
  • 作用:将ptr所指向的内存空间的大小改为size个字节。
    如果新分配的内存比原内存大, 那么原内存的内容保持不变,增加的空间不进行初始化。
    如果新分配的内存比原内存小,那么新内存保持原内存的内容,增加的空间不进行初始化。
    返回指向新分配空间的指针。若内存不够,则返回NULL,原ptr指向的内存区不变。
  • 举例说明:
int * number;
int * renumber;
number = (int *)calloc(5, sizeof(int))
if (NULL == number)//判断调用是否成功,不成功就退出
{
    exit(0);
}

renumber = (int *)realloc(number, 3 * sizeof(int));
if (NULL != renumber)//如果分配成功,就让number指向新分配的内存,这样不会造成内存泄漏,因为number原来指向的内存已经被自动回收。
{ 
    number = renumber;
}
renumber = NULL;
//...
free(number);//这里只需要free number就可以了。
number = NULL;

注意:
(1)如果size为0:
- 在C90(C++98)标准里,会回收ptr指针指向的内存,并且返回空指针。
- 在C99(C++11)标准里,会返回一个不能被引用的地址(不确定是不是空指针,取决于不同的库实现)
(2)如果函数调用失败,会返回一个空指针,ptr所指向内存也不会被回收,即会保持原来的ptr不变(地址不变,内容不变)。
(3)如果返回的是空指针:
- 在C90(C++98)标准里可能性有两种:
1).size为0(ptr指向的地址将会被回收);
2).函数没有申请到内存空间(ptr指向的地址将不会改变)
- 在C99(C++11)标准里只有一种可能:函数申请内存空间失败。

4.free

  • 声明:
void free (void* ptr);
  • 作用:回收由malloc/calloc/realloc分配的内存空间。

5.malloc/calloc/realloc三者的异同

  • 不同:
    malloc/realloc不对新分配的内存进行初始化,当前值不确定,如果要使用这两个函数分配内存,必须使用memset函数对其内存初始化为0;而calloc分配的内存全部初始化为0;
int* p=NULL;
p=(int*)malloc(sizeof(int));
if(p==NULL)
//...
memset(p,0,siezeof(int));
  • 相同:
    (1)malloc/calloc/realloc(以及free),都是C标准提供的来实现堆上内存管理的函数,使用这些函数需要包含头文件stdlib.h。
    (2)malloc/calloc/realloc均返回void*指针,使用前需要进行强制类型转换。
    (3)malloc/calloc/realloc分配的内存不再使用时需调用free进行内存回收。

你可能感兴趣的:(C语言)