C语言-动态分配内存
1. 动态分配内存是什么?
是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。通常我们的变量都是预先分配的,系统自动给分配和回收的。
2. 动态分配内存怎么用?
C99可以使用变量作为数组定义的大小,在C99之前只能使用动态分配内存实现。
int arr[n];
近似于
int* arr = (int*)malloc(n*sizeof(int));
// 操作arr如同操作int arr[n]
free(arr);
2.1 申请动态分配内存malloc()
stdlib.h
中定义函数void* malloc(size_t size)
,向系统申请大小为size
的内存空间。返回结果是void*
,使用时转换成需要的指针类型。如果申请失败,返回NULL
。
实例:获取系统最大可申请的空间
#include <stdio.h>
#include <stdlib.h>
int main(){
int cnt = 0;
while(void* p = malloc(100*1024*1024))
++cnt;
printf("%d00MB\n",cnt);
}
2.2 释放动态分配内存free()
free()
归还申请的内存。
#include <stdio.h>
#include<stdlib.h>
int main()
{
int n;
scanf("%d",&n);
int* arr = (int*)malloc(n*sizeof(int));
for(int i=0;i<n;i++){
scanf("%d",arr+i);
}
for(int i=0;i<n;i++){
printf("%d",arr[i]);
}
printf("\n");
free(arr); //归还申请的内存。
return 0;
}
free()
的注意事项:
- 不要忘记
free()
。 - 修改了申请地址,然后
free()
。
int* arr = (int*)malloc(n*sizeof(int));
free(arr+1);
- 多次
free()
。
int* arr = (int*)malloc(n*sizeof(int));
free(arr);
free(arr);
free()
非malloc
内存。
int n = 0;
free(&n);
- 一般我们需要在
free()
语句的下一条语句增加给指针置空操作,来防止野指针
free(p);
p = NULL;
2.3 初始化动态分配内存
calloc()
int* arr = (int*)calloc(n,sizeof(int));
free(arr);
近似于
int arr[n] = {0};
也可以:
int* arr = (int*)malloc(n*sizeof(int));
memset(arr,0,n*sizeof(int));
free(arr);
2.4 重新调整内存大小
realloc()
void* realloc (void* ptr, size_t size);
- 如果当前内存段后面有足够的内存空间,那么就直接扩展这段内存,
realloc()
返回原来的首地址; - 如果当前内存段后面没有足够的内存空间,那么系统会重新向内存树申请一段合适的空间,并将原来空间里的数据块释放掉,而且
realloc()
会返回重新申请的堆空间的首地址; - 如果创建失败,返回
NULL
, 此时原来的指针依然有效;
2.5 内存分配函数小结
No. | 函数 | 作用 |
---|---|---|
1 | malloc() | 分配内存块,不初始化 |
2 | calloc() | 分配内存块,初始化为0 |
3 | realloc | 调整先前分配的内存块大小 |
4 | free | 释放分配内存块 |
2.6 标准库中相关函数
No. | 函数 | 作用 |
---|---|---|
1 | memset() | 填充内存 |
2 | memcpy() | 内存拷贝 |
3 | memmove() | 内存移动 |
4 | memcmp() | 内存比较 |
5 | memchr() | 查找内存中第一个出现指定字符的位置 |
这些函数通常要加上头文件stdlib.h
或者string.h
。
练习
从终端输入未知数量的数字,按键Ctrl+D作为结束,逆序输出输入的数字。
#include<stdio.h>
#include<stdlib.h>
int main(){
int num;
int* p=NULL;
int count =0;
while(scanf("%d",&num)!=EOF){
int* t = malloc(count*sizeof(int));
if(NULL!=p){
for(int i=0;i<count;i++){
t[i]=p[i];
}
t[count]=num;
free(p);
p=t;
}else{
p=t;
p[count]=num;
}
count++;
}
for(int i=count-1;i>=0;i--){
printf("%d",p[i]);
}
printf("\n");
}
简化后为:
#include<stdio.h>
#include<stdlib.h>
int main(){
int num;
int* p=NULL;
int count =0;
while(scanf("%d",&num)!=EOF){
++count;
p = realloc(p,count*sizeof(int));
p[count-1]=num;
}
for(int i=count-1;i>=0;i--){
printf("%d",p[i]);
}
printf("\n");