malloc 函数:从堆上分配内存
calloc 函数: 从堆上分配内存并清零
realloc 函数:在之前分配的内存块的基础上,将内存重新分配为更大或者更小的部分
free 函数:将内存块返回堆
C 库函数 void *malloc(size_t size) 分配所需的内存空间,并返回一个指向它的指针。如果内存不足,则会返回NULL。
1、从堆上分配内存
2、内存不会被修改或者清空
3、返回首字节的地址
4、malloc可分配的最大内存是跟系统相关的
5、初始化全局变量用malloc函数,,不能使用赋值语句的形式在外部赋值,必须出现在函数中。(例子2)
6、初始化不能使用静态。(例子3)
例1
#include
#include
int main()
{
char *str;
str = (char *)malloc(6);//申请一个6个char类型的内存
strcpy(str, "ABCDE");//字符 A B C D E '\0' 共6个
printf("String = %s, Address = %u\n", str, str);
}
当malloc无法分配内存时候会返回NULL,可以用下面的方法进去检查是不错的做法。
#include
#include
int main()
{
int*str = (int *)malloc(sizeof(int));
if(str !=NULL)
{
printf("true\r\n");
}
else
{
printf("false\r\n");
}
}
例2
错误写法
#include
#include
char *str;
str = (char *)malloc(6);//不可以在外部赋值一个6个char类型的内存
int main()
{
strcpy(str, "ABCD");//字符 A B C D E '\0' 共6个
printf("String = %s, Address = %u\n", str, str);
}
正确写法
#include
#include
char *str;
int main()
{
str = (char *)malloc(6);//申请一个6个char类型的内存
strcpy(str, "ABCD");//字符 A B C D E '\0' 共6个
printf("String = %s, Address = %u\n", str, str);
}
例3
#include
#include
int main()
{
static char *str = (char *)malloc(6);//不可以使用静态变量申请
strcpy(str, "ABCD");//字符 A B C D E '\0' 共6个
printf("String = %s, Address = %u\n", str, str);
}
calloc函数分配内存的同时清空内存
函数原型 void *calloc(size_t nitems, size_t size)
nitems -- 要被分配的元素个数。
size -- 元素的大小。
calloc函数根据nitems和size 两个参数的成绩来分配内存,并返回一个指向内存的第一个字节的指针,如果不能分配内存,则返回一个NULL。
int *p calloc(5,sizeof(int))
内存需要清零可以使用calloc,不过执行calloc可能比执行malloc慢。
时不时地增加或减少指针分配的内存。
函数原型:void *realloc(void *ptr , size_t size);
realloc 函数返回指向内存块的指针,该函数接受两个参数,第一个参数指向原内存块的指针,第二个是请求的大小。重新分配的块大小和第一个参数引用的块大小不同。返回值是指向重新分配的内存的指针。
请求的内存大小,如果比当前分配的小,那么多余的内存会还给堆,不能保证多余的内存会被清空。
如果比当前分配的大,那么可能就在紧挨着当前分配内存的区域分配新的内存,否则就会在堆的其他区域分配 并把旧的内存赋值到新区域。
内存缩小
#include
#include
int main()
{
char *str2 ;
char *str1 ;
str1 = (char *)malloc(10);
strcpy(str1, "ABCD123");//字符 A B C D E '\0' 共6个
printf("String = %s, Address = %p\n", str1, str1);
str2 =realloc(str1,2);
printf("String = %s, Address = %p\n", str2, str2);
return(0);
}
//内存缩小
堆管理可以重用原始的内存块,且不会修改其内容。不过程序继续使用的内存超过请求的8字节,所以不会报错,但是很危险。
内存扩大
释放内存 void free(void *p) ,释放之前有调用 calloc、malloc 或 realloc 所分配的内存空间,*p指针指向一个要释放内存的内存块。
int *p = (int*)malloc(sizeof(int));
...
free(*p)
1、不能重复释放同一块内存。
2、free函数应该在同一层管理内存的分配和释放。比如说如果在函数内分配内存,那么就要在同一个函数内释放它。