为什么我们不能在堆栈上分配动态内存?

2024-01-15

在堆栈上分配内容非常棒,因为我们有 RAII,并且不必担心内存泄漏等问题。然而有时我们必须在堆上分配:

  • 如果数据真的很大(推荐)——因为堆栈很小。

  • 如果要分配的数据的大小仅在运行时才知道(动态分配)。

两个问题:

  1. 为什么我们不能分配动态内存(即大小为 仅在运行时知道)在堆栈上?

  2. 为什么堆上的内存只能通过指针来引用,而栈上的内存可以通过普通变量来引用? IE。Thing t;.

编辑:我知道一些编译器支持可变长度数组 - 这是动态分配的堆栈内存。但这确实是一般规则的一个例外。我有兴趣了解为什么我们通常不能在堆栈上分配动态内存的根本原因 - 其技术原因及其背后的原因。


为什么我们不能在堆栈上分配动态内存(即大小仅在运行时才知道的内存)?

实现这一点比较复杂。由于完成的可执行文件需要包含才能工作的指令类型,每个堆栈帧的大小都会被烧录到编译的程序中。例如,函数局部变量的布局和其他内容实际上是通过其低级汇编代码中描述的寄存器和内存地址硬编码到程序中的:“变量”实际上并不存在于可执行文件中。让这些“变量”的数量和大小在编译运行之间发生变化会使这个过程变得非常复杂,尽管这并非完全不可能(正如您所发现的,使用非标准变长数组).

为什么堆上的内存只能通过指针来引用,而栈上的内存可以通过普通变量来引用

这只是语法的结果。 C++ 的“正常”变量恰好是那些具有自动或静态存储持续时间的变量。语言的设计者could从技术上来说,你可以写一些类似的东西Thing t = new Thing只需使用一个t一整天,但他们没有;同样,这会更难实施。那么如何区分不同类型的对象呢?请记住,您编译的可执行文件必须记住自动销毁一种而不是另一种。

我很想详细说明为什么这些事情很困难,为什么不困难,因为我相信这就是您在这里所追求的。不幸的是,我的装配知识太有限了。

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

为什么我们不能在堆栈上分配动态内存? 的相关文章

  • 注销租约抛出 InvalidOperationException

    我有一个使用插件的应用程序 我在另一个应用程序域中加载插件 我使用 RemoteHandle 类http www pocketsilicon com post Things That Make My Life Hell Part 1 App
  • Directory.Delete 之后 Directory.Exists 有时返回 true ?

    我有非常奇怪的行为 我有 Directory Delete tempFolder true if Directory Exists tempFolder 有时 Directory Exists 返回 true 为什么 可能是资源管理器打开了
  • 为什么 int8_t 和用户通过 cin 输入显示奇怪的结果[重复]

    这个问题在这里已经有答案了 一小段代码让我发疯 但希望你能阻止我跳出窗外 看这里 include
  • 提交后禁用按钮

    当用户提交付款表单并且发布表单的代码导致 Firefox 中出现重复发布时 我试图禁用按钮 去掉代码就不会出现这个问题 在firefox以外的任何浏览器中也不会出现这个问题 知道如何防止双重帖子吗 System Text StringBui
  • 在 DataView 的 RowFilter 中选择 DISTINCT

    我试图根据与另一个表的关系缩小 DataView 中的行范围 我使用的 RowFilter 如下 dv new DataView myDS myTable id IN SELECT DISTINCT parentID FROM myOthe
  • 当我们想要返回对象的引用时,为什么我们在赋值运算符中返回 *this 而通常(而不是 this)?

    我正在学习 C 和指针 我以为我理解了指针 直到我看到这个 一方面 asterix 运算符是解引用的 这意味着它返回值所指向的地址中的值 而与号 运算符则相反 它返回值存储的地址记忆 现在阅读有关赋值重载的内 容 它说 我们返回 this因
  • 使用 LINQ2SQL 在 ASP.NET MVC 中的各种模型存储库之间共享数据上下文

    我的应用程序中有 2 个存储库 每个存储库都有自己的数据上下文对象 最终结果是我尝试将从一个存储库检索到的对象附加到从另一个存储库检索到的对象 这会导致异常 Use 构造函数注入将 DataContext 注入每个存储库 public cl
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 如何使用 LINQ2SQL 连接两个不同上下文的表?

    我的应用程序中有 2 个数据上下文 不同的数据库 并且需要能够通过上下文 B 中的表的右连接来查询上下文 A 中的表 我该如何在 LINQ2SQL 中执行此操作 Why 我们正在使用 SaaS 产品来跟踪我们的时间 项目等 并希望向该产品发
  • 由 IHttpClientFactory 注入时模拟 HttpClient 处理程序

    我创建了一个自定义库 它会自动为依赖于特定服务的 Polly 策略设置HttpClient 这是使用以下方法完成的IServiceCollection扩展方法和类型化客户端方法 一个简化的例子 public static IHttpClie
  • qdbusxml2cpp 未知类型

    在使用 qdbusxml2cpp 程序将以下 xml 转换为 Qt 类时 我收到此错误 qdbusxml2cpp c ObjectManager a ObjectManager ObjectManager cpp xml object ma
  • 在一个平台上,对于所有数据类型,所有数据指针的大小是否相同? [复制]

    这个问题在这里已经有答案了 Are char int long 甚至long long 大小相同 在给定平台上 不能保证它们的大小相同 尽管在我有使用经验的平台上它们通常是相同的 C 2011 在线草稿 http www open std
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • CMake 无法确定目标的链接器语言

    首先 我查看了this https stackoverflow com questions 11801186 cmake unable to determine linker language with c发帖并找不到解决我的问题的方法 我
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • 将 MQTTNet 服务器与 MQTT.js 客户端结合使用

    我已经启动了一个 MQTT 服务器 就像this https github com chkr1011 MQTTnet tree master例子 该代码托管在 ASP Net Core 2 0 应用程序中 但我尝试过控制台应用程序 但没有成
  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • C++ 条件编译

    我有以下代码片段 ifdef DO LOG define log p record p else define log p endif void record char data 现在如果我打电话log hello world 在我的代码中

随机推荐

  • Recharts 设置显示数字的 Y 轴值基数

    您好 我正在尝试使用 Recharts 显示一些数据 但遇到了问题 我要显示的数字太大 我的 Y 轴被网页截断 他们是否有一种方法来设置或自定义 Y 轴值以显示 10K 10M 等 而不是根据数据显示 10 000 和 10 000 000
  • 如何从 mongoose 获取 mongodb 版本

    很简单 使用 mongo cli db version 我怎样才能对猫鼬做同样的事情 如何发送自定义命令 您可以使用本机 mongodb 驱动程序Admin buildInfo http mongodb github com node mo
  • 在 R 中格式化日期,不带前导零

    有没有办法使用format日期对象上的函数 特别是类的对象POSIXlt POSIXct or Date 格式为 Y m d以便从这 3 个字段中的每一个字段中去除前导零 例如 我想format as Date 1998 09 02 Y m
  • 在 JavaScript 数组中分散数字

    我有一个数组10 数字 它们代表圆上的坐标 以度为单位 即每个数字都位于两者之间0 and 359 999999 我试图解决的问题是 当我在圆圈上绘制项目时 通过 html5 canvas api 有时它们会聚集在一起 导致项目相互绘制 因
  • 在 downloadHandler 中将使用 grid.draw() 创建的图下载为 png

    我在下载 Shiny 中 downloadHandler 函数中使用 grid draw 创建的绘图时遇到问题 这是我想要实现的目标的可重现示例 library gtable library ggplot2 ui lt shinyUI fl
  • 当值超过阈值时不同的标记颜色

    这是该情况的简化图 http postimg org image qkdm6p31p http postimg org image qkdm6p31p 我希望对高于某个阈值的值有一个红色标记 在这种情况下 红线上方的两个点有一个红色标记 在
  • 当表单具有 id='submit' 值的提交按钮时,表单提交不起作用

    While 这个jsfiddle http jsfiddle net 3at8d4b9 works
  • 警告:preg_match() [function.preg-match]:未知修饰符“/”[重复]

    这个问题在这里已经有答案了 我正在尝试使用 preg match 返回页面源代码中 中包含的所有 URL 我正在使用的代码是 preg match http code matches 我收到以下错误 Warning preg match f
  • 这是参考什么?

    假设我有这样的课程 public class class1 extends Applet implements Runnable private String s private URL u 还有第二类 class TS extends T
  • Git“NO-HEAD”声明

    我在 Eclipse 中使用 EGit 插件 但每当我将项目添加到 Git 时 该插件都会在 Eclipse 目录视图中的项目文件夹旁边放置一个 NO HEAD 指示 难道我做错了什么 这是什么意思 它可以简单地意味着 在您进行第一次添加和
  • 如何以编程方式获取sqlite中所有表的列表

    如何以编程方式获取 sqlite 中所有可用表的列表 尝试这个 SELECT FROM sqlite master where type table
  • IsEnabled 的 WPF 元素数据绑定(但为 false)

    我是 WPF 的初学者 有一些事情我似乎无法弄清楚 我有一个CheckBox我想禁用时RadioButton未选择 我当前的语法是
  • 本地网络上的 Meteor 应用

    我正在学习如何使用 Meteor 如下所示教程 https www meteor com try 我知道 Meteor 自动将应用程序托管到两者localhost和我的 IPv4 地址 在本例中 192 168 1 100 当我访问时192
  • 将联接添加到已有 select_from() 的 SQL Alchemy 表达式

    注意 这是一个关于 SQL Alchemy 表达式语言而不是 ORM 的问题 SQL Alchemy 适合向现有查询添加 WHERE 或 HAVING 子句 q select bmt gene c id select from bmt ge
  • Javascript,为什么被视为八进制

    我将 id 作为参数传递给 JavaScript 函数 因为它来自 UI 所以用零填充 但它似乎有 也许 奇怪 的行为 console log 0000020948 20948 console log 0000022115 9293 whi
  • QTableWidget::itemAt() 返回看似随机的项目

    我刚刚开始使用 Qt 所以请耐心等待 当我使用 QTableWidget gt getItemAt 时 它返回的项目与我使用 currentItemChanged 并单击同一项目时不同 我相信有必要使用 itemAt 因为我需要获取单击的任
  • 首次设置 时 FacesContext#getViewRoot() 返回 null

    我正在尝试更改一页中的 JSF 应用程序区域设置 并且这必须更改我的所有页面区域设置 我已关注此链接 效果很好JSF 中的本地化 如何记住每个会话而不是每个请求 视图选择的区域设置 https stackoverflow com quest
  • 如何在 Java 中读取也具有空值的 Excel 单元格...?

    我正在使用 Apache POI 3 6 我有一个专栏是blank 我希望能够阅读它 然后转到下一栏 即使我能解决NullPointerException问题是我无法到达下一个牢房 这是我的代码片段 HSSFCell cell row ge
  • 从 Java 程序运行 SQL 文件脚本

    我有一组 SQL 文件可以转换我的原始数据集 目前 我打开每个文件并执行它 如何执行 Java 程序中的每个文件 目标是使这个过程更加自动化 我想做类似的事情SqlScript execute myScript sql NOTE这些 SQL
  • 为什么我们不能在堆栈上分配动态内存?

    在堆栈上分配内容非常棒 因为我们有 RAII 并且不必担心内存泄漏等问题 然而有时我们必须在堆上分配 如果数据真的很大 推荐 因为堆栈很小 如果要分配的数据的大小仅在运行时才知道 动态分配 两个问题 为什么我们不能分配动态内存 即大小为 仅