1.动态内存分配存在的意义
int a = 4;
char arr[10]={0};
-
上述的开辟空间的方式,开辟大小固定,并且数组空间大小确定以后不能在改
-
这导致对于空间的使用比较局限了
-
C语言引入了动态内存开辟(所申请的内存在堆区),可以自己申请和释放空间,这样就更加灵活了
2.malloc和free
void* malloc(size_t size);
- (size_t size)指的是所申请的连续可用的内存的大小,单位为字节
- 如果开辟成功,返回一个指向开辟好了的内存的指针
- 如果开辟失败,返回NULL指针,所有使用时一定要检查,防止数据丢失
- 如果size=0,行为由编译器决定
void free (void*ptr);
- free函数用于释放动态开辟的内存
- (void*ptr)是指向释放内存的地址
- ptr指向的空间若不是动态开辟的,则free函数的行为不确定
- 若ptr为NULL,什么都不会发生
malloc和free都声明在 stdlib.h 头文件中
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = (int*)malloc(40);
if (p == null)
{
perror("malloc");
return 1;
}
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", *(p+i));
}
free(p); //p指向地址不变,只是将p指向的空间内存释放
p = null;//有必要
return 0;
}
3.calloc和realloc
void calloc(size_t num,size_t size);
- calloc函数是为num个大小为size(字节)的元素开辟一块空间,并且把每一个字节初始化为0
- 若要求初始化,可以使用calloc
void realloc(void*ptr,size_t size);
- ptr是要调整的内存地址
- size就是调整之后的大小
- 返回值为调整之后的内存起始位置
- 若原地址没有足够空间,会移到新地址
- 若调整失败则返回NULL,所有使用时也需要检查,以免数据丢失
#include<stdio.h> #include<stdlib.h> int main() { int* p = (int*)calloc(10, sizeof(int)); if (NULL != p) //检查 { int i = 0; for (i = 0; i < 10; i++) { *(p + i) = i; printf("%d ", *(p + i)); } } int* ptr = NULL; ptr = realloc(p, 80); if (p != NULL) { p = ptr; } for (int i = 0; i < 20; i++) { printf("%d ", *(p + i)); } free(p); p = NULL; return 0; }