C-内存管理

news2024/11/30 4:58:57

内存管理

堆,栈,静态区

c程序地址空间分布规则:

栈是从高地址向低地址延伸的,后创建的变量,后入栈,那么地址就越小.

image-20230512123023817

静态变量,作用域不变,声明周期发生改变.本质原因是存储位置发生改变.编译器编译的时候放到了全局数据区.

image-20230512122920529

#include<stdio.h>
#include<stdlib.h>
int g_val2;
int g_val1=10;

int main()
{
  int x=10;
  static int y=10;

  printf("代码区:%p\n",main);
  const char* str="hello yuanwei";
  printf("字符常量区:%p\n",str);
  printf("已初始化常量区:%p\n",&g_val1);
  printf("未初始化常量区:%p\n",&g_val2);
  char *p1=(char*)malloc(sizeof(char)*10);
  char *p2=(char*)malloc(sizeof(char)*10);
  char *p3=(char*)malloc(sizeof(char)*10);
  printf("堆区:%p\n",p1);
  printf("堆区:%p\n",p2);
  printf("堆区:%p\n",p3);

  printf("栈区:%p\n",&str);
  printf("栈区:%p\n",&p1);

  printf("x :%p\n",&x);
  printf("y:%p\n",&y);
  free(p1);
  free(p2);
  free(p3);
}

动态内存

动态内存开辟
#define N 10
int main()
{
	int* p = (int*)malloc(sizeof(int) * N);
	if (NULL == p)
	{
		perror("malloc fail\n");
		exit(1);
	}
	for (int i = 0; i < N; i++)
	{
		*(p + i) = i;
	}
	free(p);//堆空间申请的内存不要忘记释放
	return 0;
}
为什么要有动态内存

栈空间有限,申请不了大量内存空间.在技术方面,普通的空间申请,都是在全局或者栈区,全局一般不太建议大量使用,而栈空间有限,那么如果一个应用需要大量的内存空间的时候,需要通过申请堆空间来支持基本业务 .

在应用方面,程序员很难一次预估好自己总共需要花费多大的空间。想想之前我们定义的所有数组,因为其语法约束,我们必须得明确"指出"空间大小.但是如果用动态内存申请(malloc),因为malloc是函数,而函数就可以传参,也就意味着,我们可以通过具体的情况,对需要的内存大小进行动态计算,进而在传参申请,提供了很大的灵活性.

指针合法性

指针合法:能够被用户直接使用的,应用层面解决的.指针如果有具体指向(包含野指针),对应合法性我们是无法验证的,确认指针具体值得合法性,不是用户能做到的.

  1. 所有的指针,如果没有被直接使用,必须设置为NULL(编程规范)
  2. 函数内部,要验证指针的合法性,本质是验证指针!=NULL

系统提供检测指针是否合法的宏assert();如果内部条件不满足则中断运行,调试代码时用.assert()也无法检查野指针(随机值),语言层面是无法解决系统层面的问题的.

将开辟的空间初始化不是必须的,但是推荐.memset()

内存越界

在遍历内存空间的时候越界一些不一定会报错.并不是所有的严重问题都会显示出来.

内存泄漏

申请内存不释放.

  • 如果程序退出了,内存泄漏还存在吗?不在

  • 什么样的程序最怕内存泄漏?永远不会退出的程序(操作系统,杀毒软件,服务器程序(24小时在线))

free

只知道堆空间的起始地址,并没有告诉他要释放多少字节.

释放的字节数比10字节要多,说明最开始申请的字节就比10字节多.

image-20230513212842321

实际malloc申请空间时,系统给你的其实更多.多出来的部分就是记录这次申请的更详细的信息(内存级cookie信息)

  • 所以申请堆空间,是申请大空间更好,降低了cookie所占的比率.

  • 释放之后堆空间指针并不会被设置为NULL.

free理解

image-20230514092119567

经发现,堆空间释放前后,栈中的指针变量的值并没有被设置为NULL.释放后的空间也不能再被使用.

  • 那么所谓的释放究竟是什么?

free是在取消地址p和空间的关系,p里面的地址值可以相同但是不可再访问空间.关系也是需要用数据去维护的.

C中动态内存“管理”体现在哪

内存管理的本质其实是:空间什么时候申请,申请多少,什么时候释放,释放多少的问题。

  1. 场景:C的内存管理工作是由程序员决定的,而程序员什么时候申请,申请多少,什么时候释放,释放多少都是有场景决定的(比如上面的链表操作),而大部分书中,是讲具体操作,很少有场景,所以管理工作体现的并不直观。不过我们现在能理解即可。
  2. 其他高级语言:像java这样的高级语言,语言本身自带了内存管理,所以程序员只管使用即可。换句话说,内存管理工作,程序员是不用关心的。但是C是较为底层的语言,它的内存管理工作是暴露给程序员的,从而给程序员提供了更多的灵活性,不过,管理工作也同时交给了程序员.

链表测试:

image-20230514095718125

#define N 10
typedef struct Node
{
	int data;
	struct Node* next;
}Node_t;

Node_t* AllocNode(int data)
{
	Node_t* node = (Node_t*)malloc(sizeof(Node_t));
	if (node == NULL)
	{
		perror("malloc failed\n");
		exit(1);
	}
	node->data = data;
	node->next = NULL;
	return node;
}
void InsertNode(Node_t* head, int x)
{
	assert(head);
	Node_t* node = AllocNode(x);
	node->next = head->next;
	head->next = node;
}
void ShowList(Node_t* cur)
{
	assert(cur);
	cur = cur->next;
	while (cur)
	{
		printf("%d ",cur->data);
		cur = cur->next;
	}
	printf("->NULL\n");
}
void DeleteNode(Node_t* head)
{
	assert(head);
	Node* p = head->next;
	head->next = p->next;
	free(p);
	p = NULL;
}
int main()
{
	Node_t* head = AllocNode(0);
	printf("插入测试开始:...\n");
	for (int i = 1; i <= N; i++)
	{
		InsertNode(head,i);
		ShowList(head);
		Sleep(1000);
	}
	printf("删除测试开始:...\n");
	for (int i = 1; i <= N; i++)
	{
		DeleteNode(head);
		ShowList(head);
		Sleep(1000);
	}
	system("pause");
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/523500.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虾皮Shopee商品详情接口(item_get-根据ID取商品详情)代码封装

item_get-根据ID取商品详情接口 通过代码封装该接口可以拿到商品标题&#xff0c;商品价格&#xff0c;商品促销信息&#xff0c;商品优惠价&#xff0c;商品库存&#xff0c;sku属性&#xff0c;商品图片&#xff0c;desc图片&#xff0c;desc描述&#xff0c;sku图片&#xf…

基于阿里云服务器安装宝塔Linux面板详细流程(有图)

使用阿里云服务器安装宝塔面板教程&#xff0c;阿里云百科以ECS云服务器CentOS操作系统为例&#xff0c;安装宝塔Linux面板&#xff0c;先远程连接到云服务器&#xff0c;然后执行宝塔面板安装命令&#xff0c;系统会自动安装宝塔面板&#xff0c;安装完成后会返回面板地址、账…

JS数据分组

JS对数据进行分组_js数据分组_柳宁依的博客-CSDN博客 原理没看懂&#xff0c;增加分组显示数据部分。 <html> <head> <style> select { display: block; margin: auto; } table { border-collapse: collapse; margin: auto; } th, td { border: 1px solid b…

“裸奔”时代下,我们该如何有效应对网络攻击、数据泄露和隐私侵犯

随着互联网的普及&#xff0c;越来越多的个人信息被上传到互联网上&#xff0c;而网络攻击、数据泄露和隐私侵犯等问题也日益严重。在这个“裸奔”时代&#xff0c;如何保护我们的网络隐私成为了一项紧迫的任务。本文将介绍一些实用的技巧和工具&#xff0c;帮助我们有效应对网…

不强制存储的ListModel和ComboBoxModel

主方法代码&#xff1a; package com.aynu.layout;import com.aynu.model.NumberComboBoxListModel; import com.aynu.model.NumberListModel;import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import j…

从零开始 Spring Boot 28:资源

从零开始 Spring Boot 28&#xff1a;资源 图源&#xff1a;简书 (jianshu.com) Resource 接口 Spring中的资源被抽象为一个Resource接口&#xff1a; public interface Resource extends InputStreamSource {boolean exists();boolean isReadable();boolean isOpen();boole…

【人像抠图】使用vs2022,onnxruntime框架进行部署(视频和多图片处理)

一、人像抠图的应用场景 1. 图像编辑:在图像编辑软件中,人像抠图是常用操作之一。通过抠图可以将人物从原背景中分离出来,放到新背景中,实现人物换背景的效果。这在电影后期特效、游戏角色置换等领域有很广泛的应用。 2. 视频特效:在视频编辑与特效制作中,人像抠图也是关键技术…

Python的标准库argparse讲解

argparse 是 Python 的标准库之一&#xff0c;用于解析命令行参数。通过 argparse&#xff0c;你可以轻松定义你的脚本或应用程序所需的命令行参数&#xff0c;并从命令行中获取这些参数的值。 import argparse# 创建解析器 parser argparse.ArgumentParser()# 添加命令行参数…

【react 全家桶】高级指引(下)

本人大二学生一枚&#xff0c;热爱前端&#xff0c;欢迎来交流学习哦&#xff0c;一起来学习吧。 <专栏推荐> &#x1f525;&#xff1a;js专栏 &#x1f525;&#xff1a;vue专栏 &#x1f525;&#xff1a;react专栏 文章目录 13【react高级指引&#xff08;下&…

是哟Git时报错OpenSSL SSL_read: Connection was reset, errno 10054

文章目录 修改hosts的ip多尝试解除SSL验证 报错如下所示 遇到这个问题首先可以考虑开魔法或者开魔法加换个网比如开手机热点 解除SSL验证我没有试过, 我就在hosts文件中加上了ip的配置就好了 修改hosts的ip 根据网上的教程, 我试了试修改C盘中hosts文件的GitHub相关访问域名的…

QgsPoint类

在 QGIS 中&#xff0c;QgsPoint 类是用于表示二维或三维点的类。它由 X、Y 和 Z 坐标组成&#xff0c;并且可以带有一个可选的 M 值&#xff08;也称为测量值&#xff09;。以下是 QgsPoint 类的主要参数介绍&#xff1a; x&#xff1a;表示点的横向坐标值。y&#xff1a;表示…

在 Windows 上安装 scoop

一、前言 个人主页: ζ小菜鸡大家好我是ζ小菜鸡&#xff0c;让我们一起学习在在 Windows 上安装 scoop。如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连) 二、 scoop是什么 windows下的安装源搜索工具&#xff0c;有点类似centos下的yum和Ubuntu下的apt。用这个拉下来安装…

路径规划算法:基于粒子群优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于粒子群优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于粒子群优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法…

100+套大数据可视化模板

由于公司项目里面用到一个数据可视化大屏页面&#xff0c;自己网上各种谷歌百度&#xff0c;发现资源良莠不齐&#xff0c;而且大多数都是收费的&#xff0c;甚至一个页面一收费的那种。 前前后后自己不管是付费的还是免费的收集了不少&#xff0c;于是自己打算整理下&#xf…

应届生如何在职场中提高竞争力?这些方法和策略不容错过!

当前就业形势严峻&#xff0c;对于即将步入职场的应届生来说&#xff0c;提高自己的竞争力显得尤为重要。那么&#xff0c;要如何提高自己的职场竞争力呢&#xff1f;本文将为你分享一些有效的方法和策略&#xff0c;帮助你在职场中获得更好的发展。 一、提高自身素质 职场中&…

JWT 入门

1.介绍 JSON Web Token&#xff08;JWT&#xff09;是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。该token被设计为紧凑且安全的&#xff0c;特别适用于分布式站点的单点登录&#xff08;SSO…

华为OD机试真题 Java 实现【猜字谜】【2023Q1 100分】

一、题目描述 小王设计了一人简单的清字谈游戏&#xff0c;游戏的迷面是一人错误的单词&#xff0c;比如nesw&#xff0c;玩家需要猜出谈底库中正确的单词。猜中的要求如 对于某个谜面和谜底单词&#xff0c;满足下面任一条件都表示猜中&#xff1a; 变换顺序以后一样的&…

115.【SpringBoot(IDEA)+Vue(Vscode)前后端交互】

SpringBootVue前后端分离 (一)、环境介绍(二)、Vscode部分1.静态资源2.配置route路由和axios异步3.配置跨域支持 (三)、IDEA部分1.创建SpringBoot项目2.创建两个实体类3.创建控制层4.配置后端响应的端口 (四)、Vue和SpringBoot交互1.同时运行IDEA和Vscode2.访问登入界面 (一)、…

C语言——操作符详解

哈喽&#xff0c;大家好&#xff0c;今天我们来学习C语言中的各中操作符。 目录 1.操作符的分类 2.算数操作符 整数的二进制表示 3.位移操作符 3.1左移操作符 3.2右移操作符 4.位操作符 5.赋值操作符 6.单目操作符 6.1 单目操作符介绍 ~ 的用法&#xff1a; 6.2 si…

冰点还原2023中文版最新电脑系统数据恢复软件

冰点还原是什么&#xff1f;对其不了解的用户可能会认为它是《冰雪奇缘》的番外篇或续篇之类的&#xff0c;其实它们俩没有半毛钱关系&#xff0c;它其实是一款系统还原备份软件。冰点还原精灵是一款强大的系统备份、还原、修复软件&#xff0c;可以在极短时间内将系统还原到初…