C语言进阶之旅(14)动态内存
Posted 一个正直的男孩
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言进阶之旅(14)动态内存相关的知识,希望对你有一定的参考价值。
许久不见,也是好久没有更新,期间其实是在刷题,刷的牛客题,里面的题不是太难也感觉上不了台面就没有写成博客,今天所带来的内容就是动态内存
动态内存
❓❓❓
- 动态内存是啥
- 他有啥用
智者模式🧐
- 动态内存是一个程序员
自己开辟
,自己释放
的一块空间,且在堆上开辟的- 大小:系统有多大它就可以有多大
- 可更改性:可以随意改变开辟空间(realloc后文将会说明)
- 相比数组这种静态的变量更加的灵活
malloc
🙊:作用
- 向内存中申请一块
连续存放
的空间,开辟成功返回空间其位置地址- 且返回的地址类型是void*所以可以根据你的DIY决定
🙉:使用方法
- void* malloc (size_t size);
- 可能开辟空间太大,电脑没那么多内存,
开辟失败
则会返回一个NULL- 避免错误使用需要对指针判断
🙈:代码
- 开辟一块10个整型空间
- 放入0~9
int main()
{
1: int *ptr=(int *)malloc(40); /*<==>*/int arr[10]
2: int *ptr2=(int*)malooc(sizeof(int)*10); /*<==>*/int arr[10]
assert(ptr&&ptr2);
for(int i=0;i<10;i++)//自己申请的多大自己清楚
{
ptr[i]=i; /*or*/ *(ptr+i)=i;
}
free(ptr);//后文说明
ptr=NULL;//后文说明
}
🐒:建议
- 上面俩种开辟方式我建议第二种
- 更方便
- 不容易错,算出类型✖️你要的个数不会少字节
calloc
🙊:作用
- 也是向内存中申请一块
连续存放
的空间,开辟成功返回空间其位置地址- 他会把
数据初始化成0
🙉:使用方法
void* calloc (size_t num, size_t size);
- 可能开辟空间太大,电脑没那么多内存,
开辟失败
则会返回一个NULL- 避免错误使用需要对指针判断
🙈:代码
开辟10个整型的空间
int main()
{
1: int *ptr=(int *)calloc(10,4); /*<==>*/int arr[10]
2: int *ptr2=(int*)calooc(10,sizeof(int)); /*<==>*/int arr[10]
assert(ptr&&ptr2);
for(int i=0;i<10;i++)//自己申请的多大自己清楚
{
ptr[i]=i; /*or*/ *(ptr+i)=i;
}
free(ptr);//后文说明
ptr=NULL;//后文说明
}
🐒:建议
- 上面俩种开辟方式我建议第二种
- 更方便
- 不容易错,算出类型✖️你要的个数不会少字节
realloc
🥶:俗话说,动态内存要想玩的好呀,没我realloc这么行呀,当里
所以他就是本次主角
🙊:作用
调整开辟好空间的大小
,合理分配- 如果之前malloc和calloc开辟空间大了或小了则用realloc条件
🙉:使用方法
void* realloc (void* ptr, size_t size);
- 可能开辟空间太大,电脑没那么多内存,
开辟失败
则会返回一个NULL- 避免错误使用需要对指针判断
- 接收新开辟空间的指针必须是
新指针
🧐 :解析为什么必须是新指针
- 开辟空间有俩种情况
- 开辟内存后面有位置可以直接追加
- 复制原来的空间,并在堆中重新开辟一块空间
🙈:代码
追加10个整型的空间
int main()
{
int *ptr2=(int*)calooc(10,sizeof(int));
assert(ptr&&ptr2);
for(int i=0;i<10;i++)//自己申请的多大自己清楚
{
ptr[i]=i; /*or*/ *(ptr+i)=i;
}
int *ptr=(int *)realloc(ptr2,sizeof(int)*20);
assert(ptr);
ptr2=ptr;
for(int i=10;i<20;i++)//自己申请的多大自己清楚
{
ptr[i]=i;
}
free(ptr);//后文说明
ptr=NULL;//后文说明
}
free
🙊:作用
释放
动态开辟的空间
🙉:使用方法
- void free (void* ptr);
🐒:建议
- 一定要释放,不然内存泄露
- 内存泄露:资源总是有限的,如果工程大,你一直申请不释放那么运行效率就慢
- 释放完要把释放掉的指针置为NULL,不然她就是野指针
- 原来指向的空间已经被释放了,他如果还指向这个位置就是野指针,还访问就是非法访问
巩固升华
🤦:题1
- INT_MAX是一个巨大的数字(几亿bit),系统没那么多空间则会开辟失败
void test() {
int *p = (int *)malloc(INT_MAX/4);
*p = 20;
free(p);
//如果p的值是NULL,就会有问题 free(p);
}
🤦:题2
他就申请10个整型
i是等于10
那么就越界访问
void test() {
int i = 0;
int *p = (int *)malloc(10*sizeof(int));
if(NULL == p)
{
exit(EXIT_FAILURE);
}
for(i=0; i<=10; i++)
{
*(p+i) = i;//当i是10的时候越界访问
}
free(p);
}
🤦:题3
free只能释放动态开辟的空间
void test() {
int a = 10;
int *p=&a;
free(p);
🤦:题4
p一直++他所指的位置改变了,所释放的空间在原本数据的末尾开始
int *ptr=(int *)malloc(40);
*p++;
free(p);
🤦:题5
多次释放err
void test() {
int *p = (int *)malloc(100);
free(p);
free(p);//重复释放
}
⌨️:修改
free参数为NULL时则啥也不做
void test() {
int *p = (int *)malloc(100);
free(p);
p=NULL;
free(p);//重复释放
}
🤦:题6
没有free内存泄露
void test() {
int *p = (int *)malloc(100);
if(NULL != p)
{
*p = 20;
}
}
int main()
{
test();
while(1);
}
🤦:题7
没有free
p是str的零时拷贝不会改变str
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);//传值
strcpy(str, "hello world");
printf(str);
}
⌨️:修改1
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str);//传指
strcpy(str, "hello world");
printf(str);
free(str);
str=NULL;
}
⌨️:修改1
void GetMemory(char *p)
{
p = (char *)malloc(100);//动态开辟的内存是不会释放的
return p;
}
void Test(void)
{
char *str = NULL;
str=GetMemory(&str);//传值
strcpy(str, "hello world");
printf(str);
free(str);
str=NULL;
}
🤦:题8
p是在栈上零时开辟的,函数结束时他的生命周期结束了
str接收则是一个野指针
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
🤦:题9
没有free,内存泄露
void GetMemory(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
🤦:题10
str提前释放,越界访问
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
专业团队为你服务
以上是关于C语言进阶之旅(14)动态内存的主要内容,如果未能解决你的问题,请参考以下文章
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段