C++ 中的堆栈、静态和堆

2023-12-01

我查了一下,但对这三个概念不太理解。我什么时候必须使用动态分配(在堆中)以及它的真正优势是什么?静态和堆栈有什么问题?我可以编写整个应用程序而不在堆中分配变量吗?

我听说其他语言包含“垃圾收集器”,因此您不必担心内存。垃圾收集器做什么?

你可以自己操作内存做哪些使用垃圾收集器做不到的事情?

曾经有人对我说,有了这样的声明:

int * asafe=new int;

我有一个“指向指针的指针”。这是什么意思?它不同于:

asafe=new int;

?


类似的问题被问到,但它没有询问静力学。

静态内存、堆内存和堆栈内存的概述:

  • 静态变量基本上是一个全局变量,即使您无法全局访问它。通常,可执行文件本身有一个地址。整个程序只有一份副本。无论您进入函数调用(或类)多少次(以及在多少个线程中!),变量都引用相同的内存位置。

  • 堆是一堆可以动态使用的内存。如果你想要一个对象 4kb,那么动态分配器将查看堆中的可用空间列表,挑选一个 4kb 块,然后将其提供给你。通常,动态内存分配器(malloc、new 等)从内存末尾开始并向后工作。

  • 解释堆栈如何增长和收缩有点超出了这个答案的范围,但足以说明您总是只从末尾添加和删除。堆栈通常从高地址开始,然后向下增长到较低的地址。当堆栈在中间某处遇到动态分配器时,您就会耗尽内存(但请参考物理内存与虚拟内存和碎片)。多个线程将需要多个堆栈(进程通常为堆栈保留一个最小大小)。

当您想要使用每一个时:

  • 静态/全局变量对于您知道始终需要并且永远不想释放的内存非常有用。 (顺便说一句,嵌入式环境可能被认为只有静态内存......堆栈和堆是由第三种内存类型共享的已知地址空间的一部分:程序代码。程序通常会对其进行动态分配当它们需要诸如链表之类的东西时,静态内存。但无论如何,静态内存本身(缓冲区)本身并不是“分配”的,而是为此目的从缓冲区所持有的内存中分配了其他对象。您可以这样做在非嵌入式中也是如此,控制台游戏经常会避开内置的动态内存机制,转而通过对所有分配使用预设大小的缓冲区来严格控制分配过程。)

  • 当您知道只要函数在作用域内(在堆栈上的某个位置),您就会希望保留变量时,堆栈变量非常有用。堆栈对于它们所在的代码需要但在该代码之外不需要的变量来说非常有用。当您访问资源(例如文件)并希望资源在您离开该代码时自动消失时,它们也非常有用。

  • 当您想要比上述更灵活时,堆分配(动态分配的内存)非常有用。通常,会调用函数来响应事件(用户单击“创建框”按钮)。正确的响应可能需要分配一个新对象(一个新的 Box 对象),该对象应在函数退出后很长时间内保留,因此它不能位于堆栈上。但您不知道在程序开始时需要多少个盒子,因此它不可能是静态的。

垃圾收集

最近我听说了很多关于垃圾收集器有多么出色的说法,所以也许一些反对的声音会有所帮助。

当性能不是一个大问题时,垃圾收集是一个很好的机制。我听说 GC 变得越来越好、越来越复杂,但事实是,您可能被迫接受性能损失(取决于用例)。如果你很懒,它仍然可能无法正常工作。在最好的情况下,垃圾收集器会意识到,当它意识到不再有对它的引用时,您的记忆就会消失(请参阅引用计数)。但是,如果您有一个引用自身的对象(可能通过引用另一个引用回来的对象),那么单独的引用计数并不表明可以删除内存。在这种情况下,GC 需要查看整个引用汤并找出是否存在仅由其自身引用的岛屿。顺便说一句,我猜这是一个 O(n^2) 操作,但无论它是什么,如果您完全关心性能,它可能会变得很糟糕。 (编辑:马丁·B指出对于相当高效的算法来说,它的复杂度是 O(n)。如果您关心性能并且可以在恒定时间内释放而不进行垃圾回收,那么这仍然是 O(n) 太多。)

就我个人而言,当我听到人们说 C++ 没有垃圾收集时,我的想法是将其标记为 C++ 的一个功能,但我可能属于少数。对于人们来说,学习 C 和 C++ 编程最难的事情可能是指针以及如何正确处理动态内存分配。其他一些语言,比如 Python,如果没有 GC,就会很糟糕,所以我认为这取决于你想要从语言中得到什么。如果你想要可靠的性能,那么没有垃圾回收的 C++ 是我能想到的 Fortran 方面唯一的东西。如果您想要易用性和辅助轮(为了避免崩溃,而不需要您学习“正确的”内存管理),请选择带有 GC 的东西。即使您知道如何很好地管理内存,它也会节省您的时间,您可以将这些时间用于优化其他代码。实际上不再有太大的性能损失,但如果您确实需要可靠的性能(以及准确了解幕后发生的情况、时间和情况的能力),那么我会坚持使用 C++。我听说过的每个主要游戏引擎都是 C++ 语言(如果不是 C 语言或汇编语言),这是有原因的。 Python 等语言适合编写脚本,但不适用于主要游戏引擎。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 中的堆栈、静态和堆 的相关文章

  • Tensorflow 中的自定义资源

    由于某些原因 我需要为 Tensorflow 实现自定义资源 我试图从查找表实现中获得灵感 如果我理解得好的话 我需要实现3个TF操作 创建我的资源 资源的初始化 例如 在查找表的情况下填充哈希表 执行查找 查找 查询步骤 为了促进实施 我
  • 赋值运算符和复制构造函数有什么区别?

    我不明白C 中赋值构造函数和复制构造函数之间的区别 是这样的 class A public A cout lt lt A A lt lt endl The copy constructor A a b The assignment cons
  • 当我单击 C# 中的“取消”按钮时重定向到新页面(Web 部分)

    Cancel button tc new TableCell btnCancel new Button btnCancel Text Cancel btnCancel Click new EventHandler btnCanel Clic
  • 在 OpenCL 中将函数作为参数传递

    是否可以在 OpenCL 1 2 中将函数指针传递给内核 我知道可以用C实现 但不知道如何在OpenCL的C中实现 编辑 我想做这篇文章中描述的同样的事情 在 C 中如何将函数作为参数传递 https stackoverflow com q
  • 处理 fanart.tv Web 服务响应 JSON 和 C#

    我正在尝试使用 fanart tv Webservice API 但有几个问题 我正在使用 Json Net Newtonsoft Json 并通过其他 Web 服务将 JSON 响应直接反序列化为 C 对象 这里的问题是元素名称正在更改
  • 在 C++11 中省略返回类型

    我最近发现自己在 C 11 模式下的 gcc 4 5 中使用了以下宏 define RETURN x gt decltype x return x 并编写这样的函数 template
  • try-catch 中未处理的异常

    try list from XElement e in d Descendants wix File where e Attribute Name Value Contains temp Name e Parent Parent Attri
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • VS30063:您无权访问 https://dev.azure.com

    我正在尝试在 asp net core 2 1 mvc 应用程序中使用以下代码连接 Azure DevOps Uri orgUrl new Uri https dev azure com xxxxx String personalAcces
  • 在 C# 中将位从 ulong 复制到 long

    所以看来 NET 性能计数器类型 http msdn microsoft com en us library system diagnostics performancecounter aspx有一个恼人的问题 它暴露了long对于计数器
  • 转到 C# WPF 中的第一页

    我正在 WPF 中使用导航服务 为了导航到页面 我使用 this NavigationService Navigate new MyPage 为了返回我使用 this NavigationService GoBack 但是如何在不使用的情况
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • 通过等待任务或访问其 Exception 属性都没有观察到任务的异常

    这些是我的任务 我应该如何修改它们以防止出现此错误 我检查了其他类似的线程 但我正在使用等待并继续 那么这个错误是怎么发生的呢 通过等待任务或访问其 Exception 属性都没有观察到任务的异常 结果 未观察到的异常被终结器线程重新抛出
  • 是否有一个 C++ 库可以从 PDF 文件中提取文本,例如 PDFBox for Java? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 去年 我使用 PDFBox 在 Java 中创建了一个应用程序来获取某些 PDF 文件中的原始文本 现在
  • 如何检测 C# 中该字典键是否存在?

    我正在使用 Exchange Web 服务托管 API 和联系人数据 我有以下代码 即功能性的 但并不理想 foreach Contact c in contactList string openItemUrl https service
  • boost::program_options:带有固定和可变标记的参数?

    是否可以在 boost program options 中使用此类参数 program p1 123 p2 234 p3 345 p12 678 即 是否可以使用第一个标记指定参数名称 例如 p 后跟一个数字 是动态的吗 我想避免这种情况
  • Azure函数版本2.0-应用程序blobTrigger不工作

    我有一个工作功能应用程序 它有一个 blob 输入和一个事件中心输出 在测试版中工作 随着最新的更改 我的功能不再起作用 我尝试根据发行说明更新 host json 文件 但它没有引用 blob 触发器 version 2 0 extens
  • 如何确定母版页中正在显示哪个子页?

    我正在母版页上编写代码 我需要知道正在显示哪个子 内容 页面 我怎样才能以编程方式做到这一点 我用这个 string pageName this ContentPlaceHolder1 Page GetType FullName 它以 AS

随机推荐

  • 二维数组与一维数组的性能

    在 C 中 m n 二维数组与长度为 m n 的一维数组 对于 m 和 n 的较大值 之间在时间和空间上是否存在差异 使用一维数组访问元素会更快吗 在 C 中 二维数组只是一维数组的简洁索引方案 就像一维数组一样 二维数组分配单个连续内存块
  • 无法在 webview 上加载地理位置

    我想将地理位置加载到 android 2 1 上的 webview 中 地理定位在我的浏览器上运行良好 但在 webview 上却失败了 public class WebPageLoader extends Activity impleme
  • Pyspark:pandas_udf、grouped_agg 的多个参数

    我正在尝试应用带有两个参数的 pandas udf 但我有这个错误 首先我尝试使用一个参数 没问题 from pyspark sql functions import pandas udf PandasUDFType from pyspar
  • re.sub 中的 python 正则表达式条件 - 如何?

    是否可以使用python的正则表达式条件re sub 我尝试了多种变体但没有运气 这就是我所拥有的 import re match anything
  • Spring - 自动装配通用接口的通用实现

    我有一个小问题 这可能是微不足道的 但我以前从未遇到过 我有通用接口和它的通用实现 我想自动装配它 但发生了错误 详细信息如下 界面 Service public interface Serializing
  • Node-Webkit (nwjs) 节点远程用法

    我想知道如果我想从服务器运行应用程序的一些逻辑 功能 是否有人可以给我一个关于 节点远程 如何工作的示例 就像 我不知道在 package json 添加 node remote hostip 后该怎么做 我的服务器应该提供什么 js 文件
  • Scala:确保大括号平衡

    我正在运行代码来平衡语句中的括号 我认为我已经得到了正确的结果 但它在一个特定的陈述上失败了 我需要理解为什么 这是测试 特别是它失败了 除了编码之外 我认为我需要修复算法 有什么指示吗 def balance chars List Cha
  • 将“Cookie”放入“CookieJar”中

    我正在使用PythonRequests库来发出 HTTP 请求 我从服务器获取文本形式的 cookie 我怎样才能把它变成CookieJar里面有饼干吗 旧版本的Requests图书馆 0 14 2和更老的 当你经过时 把新的饼干放进罐子里
  • 如何使用 Jquery 或 Javascript 更改 .CSS 文件?

    我想知道是否可以使用 Jquery 或 javascript 对 css 文件进行更改 我知道 我可以动态地将 css 属性 或类 添加到 DOM 元素 但我不想要那样 我想在 css 文件中进行更改以自定义 css 文件的 css 类 请
  • 如何为 EF Code First 配置 ProviderManifestToken

    我有一个使用 EF 代码优先的 asp net MVC3 项目 对于我的单元测试 我一直使用 SQL Server CE 4 0 和 SQL Server 2008 Express 两者都与 EF 完美配合 按预期生成我的数据库 但是 当我
  • Jackson Scala JSON 反序列化为案例类

    我有一个 JSON 其形式如下 inventory productType someProduct1 details productId Some id description some description productType so
  • 如何在 Puppeteer page.$eval 中传递函数/变量? [复制]

    这个问题在这里已经有答案了 我正在使用 Puppeteer 自动填写网络表单 每次 input 字段中的名称都应更改为数组中的不同名称 如果我直接在 page eval 函数中指定一个名称 例如 Michael 一切都会按预期工作 pupp
  • 删除序列化程序创建的空 xmlns

    我有一个由 添加服务引用 操作生成的对象 并且我使用我编写的通用序列化器手动序列化它 我的问题是数据契约有一些内部对象 序列化程序将一个空的命名空间属性添加到内部对象的起始标记中 有什么办法可以阻止这种情况发生吗 让你的内部对象与根属于同一
  • Rust 中的共享循环引用

    我正在尝试实现一个非常幼稚的线程池模型 目前线程池的职责是 create一个新线程并返回对其的引用 维护已创建线程的映射 根据线程触发的不同事件来改变线程 我的主要问题是上面的要求迫使我让线程池保持一个HashMap
  • 在 Spring Boot 2.0 中使用 Web 客户端访问 HTTPS RESTful 服务抛出异常

    我必须访问一个 https Rest Web 服务 https example com 其证书已由客户端提供 其中包含 2 个 cer 文件 我创造了keystore jks and truststore jks文件和imported th
  • 为什么 bash 中的“test -n”返回“true”?

    我想知道怎么来的 test n 返回 true 例如 if test n then echo yes else echo no fi 打印 yes 即使给出了 test 理论上 一个空长度字符串作为参数以及选项 n 它检查字符串长度是否为
  • Ubuntu,Docker - proxyconnect tcp:tls:收到长度为 20527 的超大记录

    我正在运行我构建的 docker 二进制文件 如下this 当我做一个docker pull 我收到此错误 来自守护程序的错误响应 获取https registry 1 docker io v2 proxyconnect tcp tls 收
  • 如何在处理中的draw()之后删除先前的形状

    我无法弄清楚这一点 我有一个草图 上面有一些旋转的小矩形 它们在每次绘制 时轮换 然而 之前的矩形仍然可见 我尝试移动背景 但它要么删除除一个矩形之外的所有矩形 要么不会清除屏幕 我希望能够在每次绘制后清除所有矩形 这是代码 Create
  • 当我在瀑布对话框中使用自适应卡的输入形式时,ContinueDialogAsync 不起作用

    我一直在使用 EchoBot 模板 最近使用了 VirtualAssistant 模板 在之前的模板中 提交输入表单数据没有问题 但是这个模板仅仅提交输入表单数据就无法与ContinueDialogAsync配合使用 我们该如何解决这个问题
  • C++ 中的堆栈、静态和堆

    我查了一下 但对这三个概念不太理解 我什么时候必须使用动态分配 在堆中 以及它的真正优势是什么 静态和堆栈有什么问题 我可以编写整个应用程序而不在堆中分配变量吗 我听说其他语言包含 垃圾收集器 因此您不必担心内存 垃圾收集器做什么 你可以自