当前位置: 首页 > news >正文

南京做网站南京乐识好科技有限公司 网站制作

南京做网站南京乐识好,科技有限公司 网站制作,网站关键词优化是什么,长沙市建设局网站动态内存管理 1.1 为什么存在动态内存分配1.2 动态内存函数介绍2.1 malloc函数的使用2.2 free函数的使用2.3 calloc函数的使用2.4 realloc函数的使用3.1 常见的动态内存错误3.2 常见笔试题 1.1 为什么存在动态内存分配 我们已经掌握的内存开辟方式有: int val 20;…

动态内存管理

    • 1.1 为什么存在动态内存分配
    • 1.2 动态内存函数介绍
    • 2.1 malloc函数的使用
    • 2.2 free函数的使用
    • 2.3 calloc函数的使用
    • 2.4 realloc函数的使用
    • 3.1 常见的动态内存错误
    • 3.2 常见笔试题

1.1 为什么存在动态内存分配

我们已经掌握的内存开辟方式有:
int val = 20;//在栈空间上开辟四个字节
char arr[10] = { 0 };//在栈空间上开辟10个字节的连续空间
但是上述的开辟空间的方式有两个特点:
1. 空间开辟大小是固定的。
2. 数组在声明的时候,必须指定数组的长度,它所需要的内存在编译时分配。
但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道,
那数组的编译时开辟空间的方式就不能满足了。
这时,就需要动态开辟内存了...

1.2 动态内存函数介绍

开辟内存

void* malloc (size_t size);

malloc函数是在堆中连续开辟size个字节的空间,返回值为空间的起始地址,开辟失败返回NULL指针

释放内存

void free (void* ptr);

如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
如果参数 ptr 是NULL指针,则函数什么事都不做。

2.1 malloc函数的使用

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>/*void* malloc( size_t size );
*/int main()
{int arr[10] = { 0 };// 动态内存开辟int* p = (int*)malloc(40); // 开辟40个字节if (p == NULL){printf("%s\n", strerror(errno));return 1; // 给main函数返回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,10 来观看数据p = NULL; // 防止野指针,因为它指向的空间已经释放了,已经还给操作系统了,p如果不置空的话,这时候还记得地址return 0;
}

还未free时的内存状态
在这里插入图片描述

free后的内存状况
在这里插入图片描述

p=NULL 是为了防止野指针,因为它指向的空间已经释放了,已经还给操作系统了,p如果不置空的话,这时候还记得地址,如果访问的话就非法访问内存了

2.2 free函数的使用

#include <stdio.h>
#include <stdlib.h>
int main()
{int a = 10;int* p = &a; // 不是动态开辟的free(p);p = NULL;int* p2 = NULL; // 什么事都不做free(p2);return 0;
}

free函数是只能释放动态内存的,不是动态开辟的会报错

在这里插入图片描述

2.3 calloc函数的使用

void* calloc (size_t num, size_t size);

函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。

#include  <stdio.h>
#include  <stdlib.h>
#include  <errno.h>
#include  <string.h>
int main()
{int* p = (int*)calloc(10, sizeof(int));if (p == NULL){printf("%s\n",strerror(errno));return 1;}int i = 0;for (i = 0; i < 10; i++) {printf("%d ",*(p+i));}// 释放堆中的内存free(p);p = NULL;return 0;
}

在这里插入图片描述

2.4 realloc函数的使用

void* realloc (void* ptr, size_t size);
#include  <stdio.h>
#include  <stdlib.h>
#include  <errno.h>
#include  <string.h>
int main()
{int* p = (int*)malloc(40);if (p == NULL){printf("%s\n", strerror(errno));return 1;}int i = 0;for (i = 0; i < 10; i++){*(p + i) = i;}// 扩容// 要用新的指针来接收并且判断,否则,如果扩容失败会变成野指针,本来指向40个字节,扩容失败突然指向NULLint* ptr = (int*)realloc(p, 80); if (ptr != NULL){p = ptr;}for (i = 0; i < 10; i++){printf("%d ", *(p + i));}free(p);p = NULL;return 0;
}

在这里插入图片描述

需要注意的事,realloc在开辟内存空间时,存在2种情况

在这里插入图片描述

malloc和realloc函数的关联


#include <stdio.h>
#include <stdlib.h>int main()
{int* ptr = (int*)realloc(NULL, 40); // 相当于 malloc(40)return 0;
}

3.1 常见的动态内存错误

1.对NULL指针的解引用操作

#include <stdio.h>
#include <stdlib.h>int main()
{int* p = (int*)malloc(40);if (p = NULL) // err{return 1;}*p = 20;free(p);p = NULL;return 0;
}

这里如果动态开辟内存失败,p为NULL,对NULL指针进行访问就会有问题

2. 对动态开辟空间的越界访问

#include <stdio.h>
#include <stdlib.h>
int main()
{int* p = (int*)malloc(40);if (p = NULL){printf("%s\n", strerror(errno));return 1;}int i = 0;for (i = 0; i <= 10; i++) // 越界了{p[i] = i;}free(p);p = NULL;return 0;
}

3. 对非动态开辟内存使用free函数

#include <stdio.h>
#include <stdlib.h>int main()
{int a = 10;int* p = &a;free(p);p = NULL;return 0;
}

4. 使用free释放一块动态开辟内存的一部分

#include <stdio.h>
#include <stdlib.h>int main()
{int* p = (int*)malloc(40);if (p == NULL){return 1;}int i = 0;for (i = 0; i < 10; i++){// 这里p的位置被改变了,free(p)时,只释放掉了部分内存*p = i;p++;}free(p);p = NULL; return 0;
}

5. 对同一块空间的多次释放

#include <stdio.h>
#include <stdlib.h>int main()
{int* p = (int*)malloc(40);free(p);p = NULL; free(p);return 0;
}

6.动态开辟内存忘记释放(内存泄漏)

#include <stdio.h>
#include <stdlib.h>void test()
{int* p = (int*)malloc(100);int flag = 0;scanf("%d",&flag);if (flag == 5){return;}free(p);p = NULL;
}int main()
{test();return 0;
}

当flag为5时,就不会释放内存

3.2 常见笔试题

#include <stdio.h>
#include <stdlib.h>
#include <string.h>void GetMemory(char* p) // 堆中的p
{p = (char*)malloc(100);
}
void Test(void)
{char* str = NULL; // 栈中的pGetMemory(str); // 传递的是null,不是str的地址strcpy(str, "hello world"); // 将str给到空指针printf(str);
}int main()
{Test();return 0;
}

str为NULL,传递给GetMemory函数,GetMemory函数里的p是堆中的所开辟的p,然后给它开辟空间,然后返回到Test函数,这时的str依旧为NULL,然后调用strcpy函数,是把"hello world"给到NULL指针,会出现错误。

#include <stdio.h>char* GetMemory(void)
{char p[] = "hello world"; // 这里是局部变量,放置在栈中, 函数执行完就被销毁了,还给操作系统了//char* p = "hello world"; return p;
}
void Test(void)
{char* str = NULL;str = GetMemory(); // 野指针,非法访问内存了printf(str);
}int main()
{Test();return 0;
}

这里GetMemory后,返回的是局部变量的地址,放在栈中,但是这个函数执行完后这个变量就被销毁了,所以再通过指针访问这块内存空间就是非法访问内存了。

#include <string.h>
#include <stdio.h>
#include <stdlib.h>void GetMemory(char** p, int num)
{*p = (char*)malloc(num);
}
void Test(void)
{char* str = NULL;GetMemory(&str, 100);strcpy(str, "hello");printf(str);// 下列为修改后的代码//free(str);//str = NULL;
}int main()
{Test();return 0;
}

这个很容易,动态开辟内存后未能后free

在这里插入图片描述

http://www.yayakq.cn/news/253719/

相关文章:

  • 如何做搜索网站哈尔滨关键词优化报价
  • 网站建设7个基本流程图营业执照网上查询官网
  • 合肥网站建设方案维护视频交易类网页
  • 新上线的网站怎么做优化山东定制版网站建设公司
  • 哈尔滨网站建设吧wordpress腾讯云 COS
  • 太仓做网站的 太仓越秀网站建设推广
  • 网站建设上市苏州兼职网站开发
  • 自己有网站怎么推广网页制作与网站建设课堂实录
  • 手机上的软件网站建设如何建设网站论文文献
  • 开发工具和开发平台郑州企业网站seo
  • 中国石油工程建设协会网站搜狗收录提交申请
  • 哈尔滨制作企业网站门户网站建设公司流程
  • 局网站信息内容建设 自查报告快手短视频小程序
  • 网站服务器租赁需要什么手续彩灯制作公司
  • 做期货浏览哪些网站卡二卡三卡四精品
  • 润东电子科技 网站建设做电影网站要多少钱
  • 专利协会网站建设方案汽车公司网站建设
  • 怎样接做网站和软件的活励志故事网站源码
  • 重庆网站建设培训效果好的徐州网站建设
  • 石家庄建站源码如何配置php网站
  • 第二章营销型网站建设测验wordpress logy
  • 成都市青羊区城乡建设局网站东平做网站
  • 从您的角度来看_对于农产品网站的建设有什么想法或建议呢?wordpress怎么做链接
  • 网站建设后期服务协议产品推广词
  • 商城站地址黑龙江省和城乡建设厅网站
  • 是网站建设专业seo网站优化推广排名教程
  • 网站 wap大气网站背景图
  • 公司网站建设方法汕头网站制作哪家好
  • 营销网站建设选择企业网站开发需求详细文档
  • 茂名公司网站开发公司深圳百度推广开户