C++内存分配方式

文章目录

  • 1、静态内存分配
  • 2、栈内存分配
  • 3、堆内存分配
  • 4、内存池分配
  • 5、placement new
      • 语法
      • 工作原理
      • 示例
    • `placement new`
      • 应用场景

在C++ 中,内存分配主要有以下几种方式:

1、静态内存分配

  • 特点:在编译时就确定了内存的分配和释放,内存空间是在程序运行前就被预留好的,程序结束时由系统自动释放。
  • 示例:全局变量、静态局部变量都属于静态内存分配。
#include <iostream>// 全局变量,位于静态存储区
int globalVar = 10;void func() {// 静态局部变量,位于静态存储区static int staticVar = 20;staticVar++;std::cout << "Static variable value: " << staticVar << std::endl;
}int main() {std::cout << "Global variable value: " << globalVar << std::endl;for (int i = 0; i < 5; i++) {func();}return 0;
}

2、栈内存分配

  • 特点:由编译器自动分配和释放,用于存储函数的参数、局部变量等。其分配和释放速度快,遵循后进先出(LIFO)的原则。但栈的空间大小有限,通常在几KB到几MB之间,如果分配的空间超过栈的大小,就会导致栈溢出。
  • 示例
#include <iostream>void func() {// 局部变量,在栈上分配内存int localVar = 30;std::cout << "Local variable value: " << localVar << std::endl;
}int main() {func();return 0;
}

3、堆内存分配

  • 特点:由程序员手动分配和释放,使用 new 操作符进行内存分配,使用 delete 操作符释放内存。堆内存的大小只受限于系统的虚拟内存大小,相对来说空间比较灵活,但分配和释放的速度比栈内存慢,且如果程序员忘记释放内存,会导致内存泄漏。
  • 示例
#include <iostream>int main() {// 在堆上分配一个整数的内存空间int* heapVar = new int;*heapVar = 40;std::cout << "Heap variable value: " << *heapVar << std::endl;// 释放堆内存delete heapVar;return 0;
}

4、内存池分配

  • 特点:是一种预先分配一定大小内存块的技术,程序在运行过程中需要内存时,直接从内存池中获取,而不是每次都进行系统级的内存分配操作。当使用完内存后,将其归还到内存池中,而不是立即释放回系统。这样可以减少频繁的内存分配和释放操作带来的开销,提高程序的性能和效率,尤其对于大量小对象的频繁分配和释放场景效果显著。
  • 示例:以下是一个简单的内存池示例代码,实现了一个基本的内存池类,用于分配和释放固定大小的内存块。
#include <iostream>
#include <vector>class MemoryPool {
public:MemoryPool(size_t blockSize, size_t numBlocks) : blockSize(blockSize) {// 分配内存池的总大小char* pool = new char[blockSize * numBlocks];// 将每个内存块的地址加入到可用列表中for (size_t i = 0; i < numBlocks; i++) {freeBlocks.push_back(pool + i * blockSize);}}~MemoryPool() {// 释放内存池的内存delete[] freeBlocks[0];}void* allocate() {if (freeBlocks.empty()) {std::cerr << "Memory pool exhausted." << std::endl;return nullptr;}// 从可用列表中取出一个内存块void* block = freeBlocks.back();freeBlocks.pop_back();return block;}void deallocate(void* block) {// 将内存块归还到可用列表中freeBlocks.push_back(static_cast<char*>(block));}private:// 可用内存块的列表std::vector<char*> freeBlocks;size_t blockSize;
};int main() {// 创建一个内存池,每个内存块大小为16字节,共10个内存块MemoryPool pool(16, 10);// 从内存池中分配内存void* block1 = pool.allocate();void* block2 = pool.allocate();// 使用内存块...// 释放内存块回内存池pool.deallocate(block1);pool.deallocate(block2);return 0;
}

5、placement new

是C++ 中的一种特殊的内存分配方式,它允许在已分配的内存空间上构造对象。以下是关于placement new的详细介绍:

语法

placement new的语法形式为:new (place_address) type (initializers);,其中place_address是一个指向已分配内存的指针,type是要构造的对象类型,initializers是可选的构造函数参数列表。

工作原理

  • placement new不会分配新的内存,而是在给定的地址上直接构造对象。它假定所提供的内存已经足够大,能够容纳要构造的对象,并且该内存未被其他对象占用。
  • 当使用placement new时,编译器会调用对象的构造函数来初始化对象,但不会调用operator new来分配内存。

示例

下面是一个简单的示例,展示了placement new的用法:

#include <iostream>
#include <new>class MyClass {
public:MyClass() { std::cout << "MyClass constructor called" << std::endl; }~MyClass() { std::cout << "MyClass destructor called" << std::endl; }
};int main() {// 分配一块足够大的内存void* buffer = operator new(sizeof(MyClass));// 使用placement new在分配的内存上构造对象MyClass* obj = new (buffer) MyClass();// 使用obj// 手动调用析构函数obj->~MyClass();// 释放内存operator delete(buffer);return 0;
}

placement new

应用场景

  • 内存池管理:在内存池实现中,预先分配一大块内存,然后使用placement new在内存池中分配和构造对象,避免频繁地调用newdelete导致的内存碎片和性能开销。
  • 对象数组的构造:可以分配一个连续的内存块来存储对象数组,然后使用placement new逐个构造数组中的对象。
  • 嵌入对象到特定内存位置:某些情况下,可能需要将对象放置在特定的内存地址,例如与硬件设备交互或遵循特定的内存布局要求,placement new可以满足这种需求。

需要注意的是,使用placement new时,开发者需要负责确保所提供的内存是合适的,并且在对象不再使用时,要手动调用析构函数来释放资源,以避免内存泄漏和未定义行为。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习概要

文章目录 一、什么是机器学习 二、机器学习的种类 1. 有监督学习 2. 无监督学习 3.强化学习 三、机器学习的应用 四、机器学习的步骤 1. 数据的重要性 2. 数据和学习的种类 3. 可视化 一、什么是机器学习 机器学习指的是计算机根据给定的问题、课题或环境进行学习&a…

C# Winform 实现换肤,并自定义皮肤功能

具体实现原理详见 SkinHelp.cs类&#xff0c;实现了对原有控件的重绘&#xff0c;详见源码 public abstract class SkinHelp{private static SkinColor _currentSkinColor SkinColor.Default;private static BackgroundStripe _currentStripe BackgroundStripe.Default;priva…

基于FPGA的3U机箱模拟量高速采样板ADI板卡,应用于轨道交通/电力储能等

板卡简介&#xff1a; 本板为模拟量高速采样板&#xff08;ADI&#xff09;&#xff0c;主要用于电机转速和相电流检测&#xff0c;以实现电机闭环控制。 性能规格&#xff1a; 电源&#xff1a;DC5V&#xff0c;DC3.3V&#xff0c;DC15V&#xff0c;DC24V FPGA&#xff1a;…

python爬虫概述

0x00 python爬虫概述 以豆瓣的选电影模块为例&#xff0c;当查看源代码搜索猫猫的奇幻漂流瓶是搜不到的 这时服务器的工作方式应该是这样的 客户端浏览器第一次访问其实服务器端是返回的一个框架(html代码) 当客户端浏览器第二次通过脚本等方式进行访问时服务器端才返回的数据…

win10 如何用我的笔记本 接网线 远程控制 台式机

1.查看笔记本ip&#xff0c;台式机ip。确保在同一网段 可以ping通 1.1 ip在同一网段&#xff0c;但是ping不通 1.解决&#xff1a;把双方防火墙关闭 2.解决&#xff1a;当前网口&#xff0c;先禁用再启用 以上两台电脑就可以ping通了 2.设置双方电脑 启动远程控制 此电脑-》…

给管理商场消防安全搭建消防安全培训小程序全过程

一、需求沟通 “我是管理商场消防安全的嘛&#xff0c;做这个的作用呢&#xff0c;1是商场的所有商户员工可以看平面或者视频随时自学&#xff0c; 2是我们定期培训必修课程、考试&#xff0c;这个需要留存他们的手签字的签到表确认我们讲给他们听了&#xff08;免责很重要&am…

可视化图解算法:链表中倒数(最后)k个结点

1. 题目 描述 输入一个长度为 n 的链表&#xff0c;设链表中的元素的值为ai &#xff0c;返回该链表中倒数第k个节点。 如果该链表长度小于k&#xff0c;请返回一个长度为 0 的链表。 数据范围&#xff1a;0≤n≤105&#xff0c;0 ≤ai≤109&#xff0c;0 ≤k≤109 要求&am…

Quartz知识点总结

简单说明 简单的定时任务使用Timer或者ScheduledExecutorService quartz支持复杂的定时执行功能。支持ram存储&#xff08;内存存储&#xff09;和持久化存储。quartz有分布式和集群能力 简单使用 获取任务调度器Schedule。任务调度器可以管理任务。创建任务实例。使用JobB…

C语言每日一练——day_12(最后一天)

引言 针对初学者&#xff0c;每日练习几个题&#xff0c;快速上手C语言。第十二天。&#xff08;最后一天&#xff0c;完结散花啦&#xff09; 采用在线OJ的形式 什么是在线OJ&#xff1f; 在线判题系统&#xff08;英语&#xff1a;Online Judge&#xff0c;缩写OJ&#xff0…

【宇宙回响】从Canvas到MySQL:飞机大战的全栈交响曲【附演示视频与源码】

&#x1f31f; 这是星际大战系列的第三篇送福利文章&#xff0c;感谢一路以来支持和关注这个项目的每一位朋友&#xff01; &#x1f4a1; 文章力求严谨&#xff0c;但难免有疏漏之处&#xff0c;欢迎各位朋友指出&#xff0c;让我们一起在交流中进步。 &#x1f381; 项目代码…

数据结构知识点1

目录 一、时间复杂度和空间复杂度 1.1时间复杂度&#xff1a; 1.2空间复杂度&#xff1a; 二、装箱和拆箱 三、泛型 3.1泛型类的使用&#xff1a; 3.2泛型的上界&#xff1a; 3.3泛型方法&#xff1a; 一、时间复杂度和空间复杂度 1.1时间复杂度&#xff1a; 时间复杂…

华为ipd流程华为流程体系管理华为数字化转型流程数字化管理解决方案介绍81页精品PPT

华为流程体系最佳实践主要包括构建完善的流程框架&#xff0c;明确各层级流程要素与职责&#xff0c;梳理涵盖研发、采购、营销、服务、资产管理等多领域的流程&#xff0c;通过梳理业务场景和核心能力搭建差异化流程框架&#xff0c;采用自上而下与自下而上相结合的建模方法&a…

在大数据开发中ETL是指什么?

hello宝子们...我们是艾斯视觉擅长ui设计和前端数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 在数字经济时代&#xff0c;数据已成为企业最核心的资产。然而&#xff0c;分散在业务系统、日志文件…

Collection系列集合的小结+集合并发修改异常问题

一、Collection系列集合的小结 二、补充知识&#xff1a;集合的并发修改异常问题 三、Collection的其他相关知识 1. 前置知识&#xff1a;可变参数 2. 集合的工具类&#xff1a;Collections 3. 综合案例&#xff1a;斗地主游戏 &#xff08;1&#xff09;创建Card类 public c…

QT Quick(C++)跨平台应用程序项目实战教程 2 — 环境搭建和项目创建

目录 引言 1. 安装Qt开发环境 1.1 下载Qt安装包 1.2 安装Qt 1.3 安装Visual Studio 2022 1.4 在Visual Studio 2022中安装Qt插件 1.5 在Visual Studio 2022中安装大模型编程助手 2. 创建Qt Quick项目 2.1 创建新项目 2.2 项目结构 2.3 运行项目 3. 理解项目代码 3…

免密登录远程服务器shell脚本

一、脚本代码 #!/bin/bash #提示用户输入用户i名和ip地址 read -p "请输入远程服务器的用户名: " hname read -p "请输入远程服务器的IP地址: " fip read -p "请输入远程服务器的远程端口:" sdk #检查是否配置了免密登录 function sfmm(){ …

repo init 错误 Permission denied (publickey)

一、已经生成ssh-key并设置到gerrit上 二、已经设置.gitconfig &#xff08;此步骤是公司要求&#xff0c;设置gerrit地址为一个别名之类的&#xff0c;有的公司不需要&#xff09; 然后出现下面的错误&#xff0c;最后发现忘记设置git的用户名和邮箱 1. git config --globa…

卷积神经网络 - 汇聚层

卷积神经网络一般由卷积层、汇聚层和全连接层构成&#xff0c;本文我们来学习汇聚层。 汇聚层(Pooling Layer)也叫子采样层(Subsampling Layer)&#xff0c;其作用是进 行特征选择&#xff0c;降低特征数量&#xff0c;从而减少参数数量。 卷积层虽然可以显著减少网络中连接的…

C++ 头文件说明

如果一个程序足够大&#xff0c;代码功能很多&#xff0c;可以想象&#xff0c;不可能把代码写在一个cpp文件里。我们需要模块化&#xff0c;这样的好处很多&#xff0c;方便分工合作&#xff0c;可读性提高&#xff0c;调用也方便。 这个要怎么做呢&#xff1f; 很简单直接当…

【蓝桥杯】省赛:分糖果(思维/模拟)

思路 数据很小&#xff0c;直接暴力模拟。 有意思的是一个列表如何当成循环队列写&#xff1f;可以arr[(i1)%n]让他右边超出时自动回到开头。 code import os import sysn int(input()) arr list(map(int,input().split()))ans 0 while 1:arr1 arr.copy()for i in range…