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()的注意事项:

  1. 不要忘记free()
  2. 修改了申请地址,然后free()
int* arr = (int*)malloc(n*sizeof(int));
free(arr+1);
  1. 多次free()
int* arr = (int*)malloc(n*sizeof(int));
free(arr);
free(arr);
  1. free()malloc内存。
int n = 0;
free(&n);
  1. 一般我们需要在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);
  1. 如果当前内存段后面有足够的内存空间,那么就直接扩展这段内存,realloc()返回原来的首地址;
  2. 如果当前内存段后面没有足够的内存空间,那么系统会重新向内存树申请一段合适的空间,并将原来空间里的数据块释放掉,而且realloc()会返回重新申请的堆空间的首地址;
  3. 如果创建失败,返回NULL, 此时原来的指针依然有效;

2.5 内存分配函数小结

No.函数作用
1malloc()分配内存块,不初始化
2calloc()分配内存块,初始化为0
3realloc调整先前分配的内存块大小
4free释放分配内存块

2.6 标准库中相关函数

No.函数作用
1memset()填充内存
2memcpy()内存拷贝
3memmove()内存移动
4memcmp()内存比较
5memchr()查找内存中第一个出现指定字符的位置

这些函数通常要加上头文件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");
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值