[C/C++]内存管理,对内存进行操作

news2024/12/24 21:40:59

目录

一.内存结构

二.内存拷贝函数

三.栈空间与堆空间

四.变量的四种存储类型

五.函数返回值使用指针

六.常见错误总结


  • 🎈个人主页:北·海
  •  🎐CSDN新晋作者
  •  🎉欢迎 👍点赞✍评论⭐收藏
  • ✨收录专栏:C/C++
  • 🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!🤗

 

一.内存结构

  • 栈区(stack)
    • 由编辑器自动分配释放,存放函数的参数值,局部变量等
  • 堆区(heap)
    • 一般由程序员分配释放,随叫随到,挥之即走
    • new进行分配
    • delete进行销毁内存(数组用delete [] 数组名)
    • 分配了不进行释放,则为内存泄漏,如果不释放,则时间久了会将资源耗尽,程序结束
    • 可以在任务管理器内看到资源的变化
  • 全局/静态区(static)
    • 全局变量和静态变量的存储时存放在一起的,在程序编译时分配
  • 文字常量区
    • 存放常量字符串
    • 所有的字符串常量都是不被修改的,所以同一个字符串被其他指针所指向时候,地址都是一样的
    • 一下p和p1的地址都是一样的
//字符串常量
char* p = "你好";
char* p1 = "你好";

  • 程序代码区
    • 存放函数体(包括类的成员函数,全局函数)的二进制代码
    • 只存函数体内的指令,不存函数体内的变量,常量

二.内存拷贝函数

  • void* memcpy(void* dest,const void* src,size_tn)  
  • #include <string.h>
  • 功能 : 从源src所指向的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中

三.栈空间与堆空间

  • 栈空间一般为 1M - 2M
  • 在64位windows 10系统的限制时2G
  • 如果使用大的空间,最好使用堆内存
  • 1000字节 = 1k
  • 1000k   = 1 M
  • 1000M  = 1G

四.变量的四种存储类型

  • auto - 函数中所有的非静态局部变量,在c语言中可以声明为 auto int i= 0;,但是在c++里面必须省略掉int写为auto i = 0;编辑器会根据值得类型来推断该变量的类型,不能加int
  • register - 寄存器变量,没有内存地址,存在于寄存器,不属于内存,c语言保留下来的关键字,在全部变量中不能声明寄存器变量,C++的register关键字已经优化,如果我们打印他的地址,他就变成了普通的auto变量
  • static  - 使用范围有限制,但是程序不结束,该值不会释放,会一直存在,全局静态变量和局部静态变量只是作用域不同
  • extern - 变量必须为全局变量,在a.cpp文件里定义全局变量int value  = 10;,可在b.cpp函数里面声明extern int value; 则该值在b.cpp函数里面的值为10
#include <iostream>
#include "标头.h"//存放了文件2里面函数的声明
using namespace std;

static int d = 40;
//register int c = 30;//error 不能声明为全局
auto b = 20;
int value = 40;
//extern int e ;//error
extern int e = 20;//success
int main() {
	auto a = 10;
	e = 30;
	cout << e << endl;

	{
		main1();//其他文件
		static int f = 30;//success
		register int g = 30;//success
		auto h = 30;//success
		//auto int i = 30;//error 在c++中不能定义为auto int  应该省略掉int,c语言中可以定义为auto int

	}
	//cout << f << endl;error  块内定义的
	
}



//文件2
#include <iostream>
using namespace std;
extern int b;
extern int value;
int main1() {
	cout <<"b :"<< b << endl;
	cout << "value :" << value << endl;
	return 0;
}

五.函数返回值使用指针

#include <iostream>
using namespace std;

int* add(int x, int y) {
	int* sum = new int;
	*sum = x + y;
	return sum;
}

int* add1(int x, int y) {
	int sum = x + y;
	return &sum;
}

//返回局部静态变量的地址
int* add2(int x, int y) {
	static int sum = 0;
	cout << "sum ;" << sum << endl;
	sum = x + y;
	return &sum;
}

int main() {
	int* sum = nullptr;

	cout << *add1(2, 5) << endl;//error  不能使用外部函数局部变量的地址 bad

	//接收动态内存分配的地址
	sum = add(2, 9);//success 局部的堆空间,必须在外部拿到他的地址,从而对他进行释放
	cout <<"sum ;"<<sum << endl;
	delete sum;

	//接收静态内存分配的地址
	sum = add2(2, 5);
	cout << *sum << endl;
	*sum = 8888;
	add2(2, 5);//值被改变为8888
}

六.常见错误总结

  • 申请的内存被多次释放,程序会崩掉
#include <iostream>

using namespace std;

int main() {

	//动态内存被多次释放
	int* p = new int[18];
	p[0] = 0;
	//...
	delete[]p;
	//...
	delete[]p;

	//检测释放运行到次处
	cout << "come here" << endl;
}

  •  内存泄露,只开辟空间,不进行释放,次数达到一定时,会将堆区的资源耗尽
	//内存泄露
	do {
		int* p1 = new int[1024];

	} while (1 == 1);
  • 释放的内存不是申请的地址,地址偏移,导致内存不能被释放,程序无响应的崩掉
	//释放的内存不是申请的地址
	int* p2 = new int[10];
	p2[0] = 1;
	for (int i = 0; i < 10; i++) {
		p2++;
		cout << *p2 << endl;
	}
	
	delete[]p2;//此时p2的地址已经偏移了 4* 10个字节 不再是起初的p2地址,无法释放
	cout << "come here p2" << endl;

  •  释放空指针
//释放空指针
	int* p3 = NULL;

	if (1==0) {//模拟文件是否能打开
		p3 = new int;
	}
	delete p3;
	cout << "come here" << endl;
  • 释放一个内存块,但继续引用其中的内容

//释放一个内存块,又继续使用	
int* p4 = new int;

	delete p4;

	*p4 = 1;
	cout << "come here" << endl;

  •  越界访问
//越界访问
	int* p = new int[10];
	memset(p, 0, 10 * sizeof(int));
	for (int i = 0; i < 10; i++) {
		cout << *(p++) << endl;
	}
	//下面的都越界
	for (int i = 0; i < 10; i++) {
		cout << *(p++) << endl;
	}

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

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

相关文章

如何让Midjourney角色保持一致的5个核心技巧

hi&#xff0c;同学们&#xff0c;我是赤辰&#xff0c;本期是赤辰第2期AI教程或推荐实用AI工具&#xff0c;文章底部准备了粉丝福利&#xff0c;看完可以领取&#xff01; 今天给大家介绍Midjourney5个控制AI绘画角色一致性的技巧。 近期整理了学员在使用Midjourney生图时遇…

KVM中的四种简单网络模型

KVM中的四种简单网络模型&#xff0c;分别如下&#xff1a; 1、隔离模型&#xff08;QEMU内置的用户模式网络&#xff08;user mode networking&#xff09;&#xff09;&#xff1a;虚拟机之间组建网络&#xff0c;该模式无法与宿主机通信&#xff0c;无法与其他网络通信&…

3D数字孪生技术应用到河道治理的整体方案

无论是城市还是农村的污水处理厂&#xff0c;在建设完毕并稳定运行以后&#xff0c;日常的巡检是最重要的现场管理环节。污水处理由于其自身工艺的特点&#xff0c;污水处理设备众多 &#xff0c;进水水质变化大&#xff0c;处理流程长&#xff0c;这期间需要经常对设备的运行情…

java安全问题处理

一、客户端的计算不可信 1、服务端计算价格&#xff0c;如果不这么做的话&#xff0c;很可能会被黑客利用&#xff0c;商品总价被恶意修改为比较低的价格。 二、客户端提交的参数需要校验 1、误以为客户端的数据来源是服务端&#xff0c;客户端就不可能提交异常数据 2、对参数进…

『PyQt5-Qt Designer篇』| 08 Qt Designer中容器布局和绝对布局的使用

08 Qt Designer中容器布局和绝对布局的使用 1 容器布局1.1 设计容器布局1.2 保存文件并执行2 绝对布局2.1 设计绝对布局2.2 保存文件并执行1 容器布局 1.1 设计容器布局 先拖入一个容器Frame容器,然后拖入几个控件: 把拖入的控件拖入容器中: 选中容器,右键-布局-栅格布局:…

拥抱储能新时代!科士达闪耀EESA第二届中国国际储能展览会

2023年8月30日&#xff0c;EESA第二届中国国际储能展览会在苏州国际博览中心拉开帷幕&#xff0c;科士达以“零碳光储数能未来”为主题&#xff0c;亮相G3-20展台&#xff0c;多维度展现户用光储、工商业储能、大型储能等解决方案&#xff0c;彰显安全、高效、可靠的产品性能和…

Spring源码分析(八)CreateBean与DoCreateBean

写目录 一 CreateBean二 doCreateBean2.1 BeanWrapper2.2 缓存删除2.3 实例化Bean2.3.1 Supplier创建对象2.3.2 工厂创建对象2.3.3 构造器创建实例无参构造构造器依赖注入Setter的依赖注入autowireConstructor实例化instantiateBean 方法 2.4 Bean的前置处理 官网&#xff1a;H…

四川玖璨电子商务有限公司:如何给短视频做运营

短视频已经成为了人们日常生活中的娱乐方式之一。随着短视频平台的兴起&#xff0c;越来越多的人开始尝试在短视频上进行运营&#xff0c;而给短视频配上适合的音乐则是其中一项重要的工作。在本文中&#xff0c;我们将探讨如何给短视频做运营&#xff0c;特别是如何给短视频配…

Leecode76: 最小覆盖子串

这道题我的第一反应就是设置一个滑动窗口&#xff0c;因为之前遇到过类似的题目。 首先复习一下ACSII码的知识&#xff0c;ASCII码总共有128个&#xff0c;先是数字&#xff0c;然后是大写字符&#xff0c;最后才是小写字符。所以设置一个128大小的数组就可以解决这个问题。 le…

4年外包终上岸,我只能说这类公司能不去就不去...

我大学学的是计算机专业&#xff0c;毕业的时候&#xff0c;对于找工作比较迷茫&#xff0c;也不知道当时怎么想的&#xff0c;一头就扎进了一家外包公司&#xff0c;一干就是4年。现在终于跳槽到了互联网公司了&#xff0c;我想说的是&#xff0c;但凡有点机会&#xff0c;千万…

Room的基本使用

参考&#xff1a;jetpack之Room数据库 目录 引言一、基本使用1. 导入相关引用2. 建表Entity3. 数据库操作类Dao4. 数据库RoomDatabase5. 简单使用 二、ViewModel LiveData Room 的结合开发1. 建表Entity2. 数据库操作类Dao3. 数据库RoomDatabase4. 仓库Repository5. ViewMode…

什么时候用增量式PID,什么时候用位置式PID

PID控制器原理&#xff1a; 增量式PID&#xff1a; 位置式PID&#xff1a; 什么时候用位置式PID&#xff0c;什么时候用增量式PID&#xff1a; 在设计PID控制器时&#xff0c;应该考虑下什么时候用增量式&#xff0c;什么时候用位置式。需要看控制器输出u与控制目标之间的关系…

大数据(六):Pandas的基础应用详解(三)

专栏介绍 结合自身经验和内部资料总结的Python教程&#xff0c;每天3-5章&#xff0c;最短1个月就能全方位的完成Python的学习并进行实战开发&#xff0c;学完了定能成为大佬&#xff01;加油吧&#xff01;卷起来&#xff01; 全部文章请访问专栏&#xff1a;《Python全栈教…

Qt应用开发(基础篇)——进度对话框 QProgressDialog

一、前言 QProgressDialog类继承于QDialog&#xff0c;是Qt设计用来反馈进度的对话框。 对话框QDialog QProgressDialog提供了一个进度条&#xff0c;表示当前程序的某操作的执行进度&#xff0c;让用户知道操作依旧在激活状态&#xff0c;配合按钮&#xff0c;用户就可以随时终…

探索FedLCM——解锁FATE部署管理的实用功能

FedLCM &#xff08;Federation Lifecycle Manager&#xff0c;联邦生命周期管理器&#xff09;是 VMware 在 2022 年贡献到 FATE 社区的开源项目&#xff0c;通过 FedLCM 的部署管理服务和任务管理服务&#xff0c;我们可以用图形化的方式完成包括 FATE 集群的云原生部署、联邦…

Acwing791. 高精度加法

Acwing791. 高精度加法 题目描述代码展示 题目描述 代码展示 #include <iostream> #include <vector>using namespace std;vector<int> add(vector<int> &A, vector<int> &B) {if (A.size() < B.size()) return add(B, A);vector<…

扎根嵌入式行业需要什么学历文凭?

在嵌入式行业&#xff0c;学历并不是唯一关键。我本人拥有电子工程学士学位&#xff0c;但嵌入式行业更看重实际技能和经验。视频后方有免费的嵌入式学习资料&#xff0c;入门和进阶内容都涵盖其中。嵌入式行业一般接纳各种学历&#xff0c;从专科到本科到研究生&#xff0c;甚…

C++——vector:resize与reserve的区别,验证写入4GB大数据时相比原生操作的效率提升

resize和reserve的区别 reserve&#xff1a;预留空间&#xff0c;但不实例化元素对象。所以在没有添加新的对象之前&#xff0c;不能引用容器内的元素。而要通过调用push_back或者insert。 resize&#xff1a;改变容器元素的数量&#xff0c;且会实例化对象&#xff08;指定或…

用Python轻松实现Word文档到PDF的批量转换

Word文件&#xff08;Doc、Docx&#xff09;和PDF文件都是使用广泛的文档格式。其中&#xff0c;Word文档格式在编辑内容时优势明显&#xff0c;能够满足各种编辑需求。但想要保证文档的完整和格式的一致&#xff0c;以及使文档有良好的跨平台兼容性&#xff0c;PDF格式则是更好…

点对点传输技术可实现更大的文件传输

互联网的早期主要是基于点对点的系统。这是一个由学者和研究人员构成的网络&#xff0c;连接到这个网络的计算机都是同等的&#xff0c;因为每台计算机都提供了尽可能多的信息。在点对点连接的初期&#xff0c;不需要考虑快速传输大型文件。 随着互联网的发展&#xff0c;客户端…