IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 动态内存管理 -> 正文阅读

[C++知识库]动态内存管理

栈内存与堆内存

声明的变量以及函数名是使用的栈内存,但是在动态内存管理中使用的是堆内存。
栈内存比较紧凑,所以有较大的局部相关性。
堆内存在运行期动态扩展,需要显示释放。new在运行期被调用 。
vector和string就是动态内存

== 一个例子来看new的用处 ==

  1. code_one
#include<iostream>
using namespace std;
int* fun()
{
	int* res = new int(2);
	return  res;
}
int main()
{
	int* y = fun();
	cout << *y << endl;
	return 0;
}
  1. code_two
#include<iostream>
using namespace std;
int* fun()
{
	int res = 2;
	return  &res;
}
int main()
{
	int* y = fun();
	cout << *y << endl;
	return 0;
}

两段代码都可以输出2;但是第二段代码很危险,因为new使用的是堆内存,需要手动释放,所以在未释放以前指针指向的内存以及内容都保留,所以可以成功输出2;但是第二段代码值存在栈内存中,在调用fun()函数以后,fun()函数中声明变量的内存就会自动释放,得到一个指针指向某地址,但是如果有其他内容存入同样的地址,那么输出的值就会使内存中存入的新值

  1. 对象的构造分为两步:分配内存与在所分配的内存上构造对象;销毁也分为两步

new的几种形式

1. 构造单一对象和单一数组

#include<iostream>
using namespace std;
int* fun()
{
	int* res = new int(0);//缺省初始化
	*res = 2;
	return  res;
}
int main()
{
	/*int* y = fun();
	cout << *y << endl;
	return 0;*/
	int A[5][5];
	int* y = new int[5]{};
	delete[] y;//表示删除的是一个数组
	cout << typeid(*A).name() << endl;
	return 0;
}

2. nothrow new

new用来开辟内存,但是如果内存已经被分配完了,或者说留下的内存空间没有我们要求的连续的内存长度,就会出现开辟失败的情况,nothrow new就可以抛出异常

#include<iostream>
#include<new>
using namespace std;

int main()
{
	int* y = new (nothrow) int[5]{};
	if (y == nullptr)
	{
		//...
	}
	cout << typeid(*A).name() << endl;
	return 0;
}

3.placement new

例子:vector对像是动态内存处理的,可以在末尾加入新元素。但是如果遇到在添加元素的时候,后边没有与对象连续的内存空间供使用,vector首元素指向了8000,在8016处是另一个对象,那么就需要把当前对象的值复制到另外一块内存中,进而可以在后边添加元素。在复制元素到新内存空间以后,并没有创建对象,只有当新元素添加以后才会创建新的对象。一般情况两下复制到的新地址出空间连续长度为目前长度的两倍。

placement new意思就是已经有一块内存了,不需要分配测内存只需要在已知的内存上构建对象。

#include<iostream>
#include<new>
#include<vector>
using namespace std;

int main()
{

	vector<int>* A = new vector<int>{1,2,3};
	cout << (*A)[0] << endl;
	int* y = new (A) int(4);//就是placement new的作用,省去了分配内存的动态,就在A指向的内存上进行构造对象
	cout << (*A)[0]<< endl;
	return 0;
}

new auto

int* y = new auto(3);

new与对象对齐

new在开辟内存的时候可以考虑到对齐信息

#include<iostream>
#include<new>
#include<vector>
using namespace std;

struct alignas(256) Str {};//alignas表示对齐信息,结构体起始地址一定为256(10进制)的整数倍
int main()
{

	Str* A = new Str;//new在开辟内存的时候可以考虑到结构体声明中的对齐信息
	cout << A<< endl;
	return 0;
}

delete常见用法

销毁单一对象和单一数组

int* ptr = new int;
delete ptr;
int* pptr = new int[5];
delete[] pptr

placement delete

与placement new对应,只销毁对象但是不把资源返归还给系统

动态内存的相关问题

sizeof不会返回动态分配的内存大小

sizeof发生在编译器;vector的动态分配内存发生在运行期

allocator分配器分配内存

#include<iostream>
#include<new>
#include<memory>
#include<vector>
using namespace std;

void fun(int* x)
{
	cout << "fun is called" << endl;
	delete x;
}
int main()
{
	allocator<int> al;
	int* ptr = al.allocate(3);//内存分配,没有初始化
	int* y = new (ptr) int[3]{ 1,2,3 };//placement new的方式进行初始化,在已经分配完的空间上进行初始化
	cout << *y+1 << endl;
	return 0;

}

malloc/free管理内存

malloc只分配内存,但是没有对象的构造;

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-19 00:58:09  更:2022-02-19 01:00:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:24:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码