如何在堆栈上分配具有灵活数组成员的结构

2024-01-08

假设我们有一个以灵活数组成员结尾的结构:

struct foo {
    size_t len;
    uint8_t data[];
};

如何在堆栈上分配这个结构(即内存在作用域结束时自动释放)?另外,如果len可以包含字段的大小data.

目前,我做的事情如下:

uint8_t buf[256];
struct foo *foo = (struct foo *)buf;
foo->len = sizeof(buf) - sizeof(struct foo);

然而,它很容易出错。用于alloca()可能会稍微好一点:

struct foo *foo = alloca(256 + sizeof(struct foo));
foo->len = 256;

从那里,我可以定义一个像这样的宏:

#define STACK_ALLOC_FOO(SIZE) ({                          \
    struct foo *_tmp = alloca(SIZE + sizeof(struct foo)); \
    _tmp->len = SIZE;                                     \
    _tmp;                                                 \
})

并声明它:

struct foo *foo = STACK_ALLOC_FOO(256);

但是,我不确定分配的内存的生命周期alloca()。是内部作用域还是函数?

另外,分配全局变量不起作用(即使这不是我主要关心的问题)。

有人有在堆栈上分配具有灵活数组成员的结构的良好实践吗?


假设我们有一个以可变长度数组 (VLA) 结尾的结构:

好吧,你不知道。你有一个以 a 结尾的结构灵活的阵列成员。不同的东西,主要用于动态内存分配场景。

如何在堆栈上分配该结构

如果没有一些非标准扩展,很难做到这一点。例如一个alloca保证返回没有内存的扩展有效型。这意味着编译器尚未在内部将内存标记为具有某种类型。否则...

结构 foo *foo = (结构 foo *)buf;

您会得到严格的别名违规未定义行为,就像上面的错误代码一样。严格的别名规则是什么? https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule

此外,您还需要注意对齐和填充。

但是,我不确定用 alloca() 分配的内存的生命周期。是内部作用域还是函数?

是的,可能是。它不是一个标准函数,我不确定是否有任何库对其行为提供了可移植的保证。它甚至不是 POSIX 函数。 Linuxman保证:

alloca() 函数在调用者的堆栈帧中分配 size 字节的空间。当调用 alloca() 的函数返回到其调用者时,该临时空间会自动释放。

我假设这适用于 *nix 下的 gcc/glibc,但不适用于其他工具链或系统。


为了获得可移植且坚固的代码,您可以做的是这样的:

struct foo {
    size_t len;
    uint8_t data[];
};

struct bar256 {
  size_t len;
  uint8_t data[256];
};

typedef union
{
  struct foo f;
  struct bar256 b;
} foobar256;

Here bar256 and foobar256可以在本地定义。您可以通过以下方式访问数据f.data or b.data of a foobar256。这种类型双关在 C 中是允许的并且是明确定义的。

此时,您可能会意识到该结构只是更麻烦,值得,只需使用两个局部变量,其中一个是实际的 VLA:

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

如何在堆栈上分配具有灵活数组成员的结构 的相关文章

  • 将复选框添加到 UniformGrid

    我正在尝试将复选框动态添加到 wpf 中的统一网格中 但看起来网格没有为它们分配足够的空间 所以它们都有点互相重叠 这就是我将它们添加到后面的代码中的方法 foreach string folder in subfolders PathCh
  • 无法使用已与其底层 RCW 分离的 COM 对象。在 oledb 中

    我收到此错误 但我不知道我做错了什么 下面的代码在backrgroundworker中 将异常详细信息复制到剪贴板 System Runtime InteropServices InvalidComObjectException 未处理 通
  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • 当 contains() 工作正常时,xpath 函数ends-with() 工作时出现问题

    我正在尝试获取具有以特定 id 结尾的属性的标签 like span 我想获取 id 以 国家 地区 结尾的跨度我尝试以下xpath span ends with id Country 但我得到以下异常 需要命名空间管理器或 XsltCon
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • 将目录压缩为单个文件的方法有哪些

    不知道怎么问 所以我会解释一下情况 我需要存储一些压缩文件 最初的想法是创建一个文件夹并存储所需数量的压缩文件 并创建一个文件来保存有关每个压缩文件的数据 但是 我不被允许创建许多文件 只能有一个 我决定创建一个压缩文件 其中包含有关进一步
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • C# 中的递归自定义配置

    我正在尝试创建一个遵循以下递归结构的自定义配置部分
  • 将自定义元数据添加到 jpeg 文件

    我正在开发一个图像处理项目 C 我需要在处理完成后将自定义元数据写入 jpeg 文件 我怎样才能做到这一点 有没有可用的图书馆可以做到这一点 如果您正在谈论 EXIF 元数据 您可能需要查看exiv2 http www exiv2 org
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • 当操作繁忙时,表单不执行任何操作(冻结)

    我有一个使用 C 的 WinForms 应用程序 我尝试从文件中读取一些数据并将其插入数据表中 当此操作很忙时 我的表单冻结并且无法移动它 有谁知道我该如何解决这个问题 这可能是因为您在 UI 线程上执行了操作 将文件和数据库操作移至另一个
  • 将 unsigned char * (uint8_t *) 转换为 const char *

    我有一个带有 uint8 t 参数的函数 uint8 t ihex decode uint8 t in size t len uint8 t out uint8 t i hn ln for i 0 i lt len i 2 hn in i
  • 将 xml 反序列化为类,list<> 出现问题

    我有以下 XML
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框
  • 使用 libcurl 检查 SFTP 站点上是否存在文件

    我使用 C 和 libcurl 进行 SFTP FTPS 传输 在上传文件之前 我需要检查文件是否存在而不实际下载它 如果该文件不存在 我会遇到以下问题 set up curlhandle for the public private ke

随机推荐

  • 在鼠标悬停时动态添加和删除类 - Vue.js

    我可以使用 Vue 成功地在鼠标悬停时添加一个类 但我想在鼠标离开元素时删除该类 在 Vue 中处理这个问题的惯用方法是什么
  • MongoDB $或查询

    我在 mongo shell 中运行以下查询 db Profiles find or name gary name rob 它只是按预期返回任何内容 JSON Use in 对于问题中的查询 使用更合适 in http docs mongo
  • Websocket 跨页面 JavaScript

    我用 JS 实现了一个基本的 websockets 客户端 function connectToNotifServer var conn new WebSocket ws localhost 8080 conn onopen functio
  • 管道、dup2 和 exec()

    我必须编写一个可以运行管道的外壳 例如像这样的命令ls l wc l 我已经成功解析了用户给出的命令 如下所示 ls 第一个cmd l frsarg wc scmd l secarg 现在我必须使用两个叉子 因为命令是两个和一个管道 我编写
  • XML 中真正允许的字符

    由于在解析某些 据说是 XML 数据时出现一些解析器错误 我查看了XML标准 http www w3 org TR REC xml d 找出真正允许的内容 我目前的疑虑是关于标签内容中允许包含哪些内容
  • 添加更多代码后,Google Apps 脚本会随机生成错误消息“发生意外错误”

    我编写了一个 Google Apps Script UiApp 应用程序 其中包含近 1000 行代码以及相当数量的处理程序和回调 该应用程序运行良好 但随着代码的增长 应用程序突然收到很多 发生意外错误 消息 错误消息在应用程序加载时出现
  • 您如何根据风格选择元素?

    使用 jQuery 您如何找到具有特定样式的元素 例如 float left 无论它是内联样式还是 CSS 文件中定义的样式 使用过滤功能 http docs jquery com Traversing filter filter func
  • 带有嵌套资源轨的嵌套表单 4

    我正在尝试在 Rails 4 0 3 上创建一个带有嵌套资源的嵌套 form for 但是我遇到了一些问题并且花了很多时间 问题是当我尝试提交表单时 这些值没有保存在我的数据库中 它将直接重定向到labs index 我已经定义了嵌套资源和
  • 为什么带宽以每秒位数来衡量?

    根据带宽的定义 它是频率的宽度 光谱 因此带宽应以 Hz 为单位进行测量 但 bps Mbps kbps 几乎到处都被用作带宽的度量 我需要知道的是 为什么使用 bps kbps 等数据传输速率测量来测量信号的带宽 由于对香农 哈特利定律的
  • 是的:将字段本身与另一个字段进行比较

    I had StartIntensity yup number EndIntensity yup number when StartIntensity StartIntensity number schema any gt return S
  • Rest 集合中的分页

    我有兴趣向 JSON 文档集合公开一个直接的 REST 接口 想想CouchDB http couchdb apache org or 坚持不懈 http persvr org 我遇到的问题是如何处理GET如果集合很大 则对集合根进行操作
  • Bootstrap 4.0.0 的 Jquery 兼容版本是什么

    请建议与Bootstrap版本4 0 0一起使用的jquery的兼容版本 也只是为了了解知识 列出了 bootstrap 和 Jquery 一起工作的版本 有什么建议或者参考 谢谢 Bootstrap 4 3 对导航栏菜单的创建方式进行了重
  • 带有 Html.ActionLink 的绝对(外部)URL

    我无法让 Html ActionLink 生成绝对网址 Html ActionLink DataBinder Eval c DataItem Name ToString DataBinder Eval c DataItem Path ToS
  • 使用 prometheus 统计 k8s 集群 cpu/内存使用情况

    我想用prometheus计算k8s集群cpu 内存使用情况 不是k8s pod使用情况 这样我就可以在grafana中显示 I use sum container memory usage bytes id 获取 k8s 集群使用的内存
  • JavaScript 中类型化数组的优点是它们在 C 中的工作方式相同或相似吗?

    我一直在玩类型化数组 https developer mozilla org en US docs JavaScript typed arrays在 JavaScript 中 var buffer new ArrayBuffer 16 va
  • Windows Azure Active Directory 应用程序中的“登录 URL”是什么?

    我已经在 Windows Azure Active Directory 中配置了我的第一个应用程序 一切正常 我可以使用目录中的帐户登录 但是 我还不完全清楚所有概念 尤其是登录网址 工具提示说 用户可以登录并使用您的应用程序的 URL 您
  • 有没有办法在Java中嵌入浏览器? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 有没有办法在Java中嵌入浏览器 更具体地说 是否有一个可以模拟浏览器的库 从 JavaFX 2 0 开始 您现在可以使用webvie
  • Java 中未处理的异常

    我目前正在学习如何正确执行自定义异常 我偶然发现了一个问题 每当我尝试使用抛出此自定义异常的类的对象时 我的 IDE 调试器 我使用的是 IntelliJ idea 会显示 未处理的异常 InsertExceptionName 代码以简化的
  • 在不活动的情况下以编程方式停止 AWS EC2

    当开发环境中没有活动 例如 2 小时不活动后 时 我们是否可以停止开发环境的 AWS Windows Server EC2 实例 我无法确定是否有任何用户虚拟连接到服务器 我可以轻松地以编程方式在固定时间启动 停止 EC2 但为了降低服务器
  • 如何在堆栈上分配具有灵活数组成员的结构

    假设我们有一个以灵活数组成员结尾的结构 struct foo size t len uint8 t data 如何在堆栈上分配这个结构 即内存在作用域结束时自动释放 另外 如果len可以包含字段的大小data 目前 我做的事情如下 uint