C++入门(内存管理)

这篇具有很好参考价值的文章主要介绍了C++入门(内存管理)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、New

  • new在开辟空间的同时会自动调用类的默认构造函数进行初始化,默认构造对于内置类型不做处理,对于自定义类型会去调用自定义类型的默认构造
#include <assert.h>
#include <stdlib.h>

// 对于内置类型而言,用malloc和new,除了用法不同,没有什么区别
// 他们区别在于自定义类型, malloc只开空间,new开空间+调用构造函数初始化
struct ListNode
{
	ListNode* _next;
	int _val;

	ListNode(int val = 0)
		:_next(nullptr)
		, _val(val)
	{}
};

struct ListNode* BuyListNode(int x)
{
	struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(node);
	node->_next = NULL;
	node->_val = x;
	return node;
}

int main()
{
	int* p1 = new int; // New1个int对象
	int* p2 = new int[10]; // New10个int对象

	int* p3 = new int(10); // New一个int对象,初始化成10
	int* p4 = new int[10]{10, 1, 2, 3};// New10个int对象,初始化成{}中的值

	// 不匹配,可能会报错,可能不会报错。建议一定要匹配
	delete p1;
	delete[] p2;//与new int[10]匹配

	delete p3;
	delete[] p4;

	//ListNode* n1 = BuyListNode(1);
	ListNode* n1 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n1);

	ListNode* n2 = new ListNode(2);
	ListNode* n3 = new ListNode(3);
	ListNode* n4 = new ListNode(4);

	return 0;
}

2、Delete

  • delete在销毁空间的同时会自动调用类的析构函数,析构函数对于内置类型不做处理,对于自定义类型会去调用自定义类型的析构函数
class Stack
{
public:
	Stack(int capacity = 0)
	{
		cout << "Stack(int capacity)" << endl;
		_a = new int[capacity];
		_capacity = capacity;
		_top = 0;
	}

	~Stack()
	{
		cout << "~Stack()" << endl;
		delete[] _a;
		_capacity = 0;
		_top = 0;
	}

class MyQueue {
public:
	MyQueue()
		: _pushST(4)
		, _popST(4)
	{}
private:
	Stack _pushST;
	Stack _popST;
};

int main()
{
	Stack st;
	Stack* ps1 = (Stack*)malloc(sizeof(Stack));
	assert(ps1);
    Stack* ps2 = new Stack; // 开空间+调用构造函数初始化

	free(ps1);
	delete ps2; // 调用析构函数清理资源 + 释放空间

	MyQueue* obj = new MyQueue;
	delete obj;

	return 0;
}

3、operator new和operator delete

operator new和operator delete是两个C++提供的库函数

int main()
{ 
	// 跟 malloc功能一样, 失败以后抛异常
	Stack* ps2 = (Stack*)operator new(sizeof(Stack));
	operator delete(ps2);

	Stack* ps1 = (Stack*)malloc(sizeof(Stack));
	assert(ps1);
	free(ps1);

	//new的底层原理,就是转换成了调用operator new和构造函数
	Stack* ps3 = new Stack;
	// call operator new
	// call Stack构造函数

	return 0;
}

4、定位New表达式(placement-new)

  • 定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
  • 使用格式:
    new (place_address) type或者new (place_address) type(initializer-list)
    place_address必须是一个指针,initializer-list是类型的初始化列表
int main()
{
	Stack* obj = (Stack*)operator new(sizeof(Stack));
	// 针对一个空间,显示调用构造函数初始化
	new(obj)Stack(4);

	return 0;
}

5、内存泄漏

1、内存泄漏是指针丢了,内存还没有释放,无法将这块空间还给内存文章来源地址https://www.toymoban.com/news/detail-412848.html

到了这里,关于C++入门(内存管理)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Taurus.MVC 微服务框架 入门开发教程:项目集成:7、微服务间的调用方式(调整):引用程序集及代码下载(新增)

    Taurus.MVC 微服务框架 入门开发教程:项目集成:7、微服务间的调用方式(调整):引用程序集及代码下载(新增)

    今天补充一下 Taurus.MVC 微服务教程,介绍一下微服务中针对RPC方面调整或新增的功能。 之前系列文章目录: Taurus.MVC 微服务框架 入门开发教程:项目集成:1、服务端:注册中心、网关(提供可运行程序下载)。 Taurus.MVC 微服务框架 入门开发教程:项目集成:2、客户端:

    2024年04月25日
    浏览(15)
  • [C语言][数据结构][动态内存空间的开辟]顺序表的实现!

    [C语言][数据结构][动态内存空间的开辟]顺序表的实现!

    目录 零.必备知识 a.顺序表的底层是数组. b.数组在内存中是连续存放的. c.动态内存空间的开辟(malloc,calloc,realloc). 一.顺序表的定义与实现          1.1 顺序表的定义          1.2 顺序表的初始化          1.3 顺序表的销毁          1.4 顺序表容量的检查与调整

    2024年04月09日
    浏览(16)
  • 【C进阶】分析 C/C++程序的内存开辟与柔性数组(内有干货)

    【C进阶】分析 C/C++程序的内存开辟与柔性数组(内有干货)

            本文是对于动态内存管理知识后续的补充,以及加深对其的理解。对于动态内存管理涉及的大部分知识在这篇文章中 ---- 【C进阶】 动态内存管理_Dream_Chaser~的博客-CSDN博客         本文涉及的知识内容主要在两方面: 简单解析C/C++程序的内存开辟 分析柔性数组

    2024年02月09日
    浏览(12)
  • C++动态开辟与C对比

    首先,我们来回顾一下不同区的特点: 1. 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是 向下增长 的。 2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口 创建共享共享内存,做进程间通信。 3. 堆用于程序运行时动态内存分

    2024年02月21日
    浏览(7)
  • 为什么创建 Redis 集群时会自动错开主从节点?

    哈喽大家好,我是咸鱼 在《一台服务器上部署 Redis 伪集群》这篇文章中,咸鱼在创建 Redis 集群时并没有明确指定哪个 Redis 实例将担任 master,哪个将担任 slave 然而 Redis 却自动完成了主从节点的分配工作 如果大家在多台服务器部署过 Redis 集群的话,比如说在三台机器上部署

    2024年02月10日
    浏览(12)
  • C++ 解引用与函数基础:内存地址、调用方法及声明

    在上一页的示例中,我们使用了指针变量来获取变量的内存地址(与引用运算符 一起使用)。但是,你也可以使用指针来获取变量的值,这可以通过使用 * 运算符(解引用运算符)来实现: 需要注意的是,符号 * 在这里可能会让人感到困惑,因为它在我们的代码中有两种不

    2024年04月12日
    浏览(12)
  • 解决用MybatisPlus修改字段时会自动忽略传值为null的字段

    产生原因 我们使用mybatis-plus框架的时候会产生一个很尴尬的情况,在使用mybatis-plus的自带封装的update的方法的时候,如果你想要修改某个字段为null值,则会自动忽略修改你这个字段,导致这个字段还是原来未修改前的值 。 解决方法 根据查阅相关资料,总结出以下几点解决

    2024年02月16日
    浏览(13)
  • 【C++内存管理】内存池

    C++17 引入了一个新的内存资源抽象层 - memory_resource 。其主要目的是将内存的分配和回收与具体的数据结构解耦,从而允许开发人员使用不同的内存管理策略,提高内存管理的灵活性。 memory_resource 是一个基类,可以用于创建和配置具有不同内存管理行为的内存池。 1.1 memory_

    2024年02月13日
    浏览(12)
  • Linux--进程间的通信-共享内存

    Linux--进程间的通信-共享内存

    前文: Linux–进程间的通信-匿名管道 Linux–进程间的通信–进程池 Linux–进程间的通信-命名管道 对于两个进程,通过在内存开辟一块空间(操作系统开辟的),进程的虚拟地址通过页表映射到对应的共享内存空间中,进而实现通信 ; 特点和作用: 高效性: 共享内存是一种

    2024年04月26日
    浏览(16)
  • C++内存管理(3)——内存池

    C++内存管理(3)——内存池

    利用默认的内存管理操作符 new/delete 和函数 malloc()/free() 在堆上分配和释放内存会有一些额外的开销。 系统在接收到分配一定大小内存的请求时,首先查找内部维护的内存空闲块表,并且需要根据一定的算法(例如分配最先找到的不小于申请大小的内存块给请求者,或者分配

    2024年02月09日
    浏览(8)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包