隐藏在 C++ 类中嵌入 char 数组中的数据成员的性能、安全性和对齐方式是什么?

2024-04-30

我最近看到一个代码库,我担心它违反了对齐约束。我已经对其进行了擦洗,以生成一个最小的示例,如下所示。简而言之,球员们是:

  • Pool。对于“高效”的某些定义,这是一个有效分配内存的类。Pool保证返回一块与请求大小对齐的内存块。

  • Obj_list。此类存储同构对象集合。一旦对象的数量超过某个阈值,它就会将其内部表示从列表更改为树。的大小Obj_list是一个指针(在 64 位平台上为 8 个字节)。其店面的客流量当然会超过这个数字。

  • 总计的。该类代表系统中非常常见的对象。它的历史可以追溯到早期的 32 位工作站时代,并且它经过“优化”(在同一个 32 位时代)以使用尽可能少的空间。总计的s 可以为空,也可以管理任意数量的对象。

在这个例子中,总计的项目总是从分配Pools,所以它们总是对齐的。唯一出现的情况是Obj_list在此示例中是“隐藏”成员总计的对象,因此它们总是使用分配安置新。以下是支持类:

class Pool
{
public:
   Pool();
   virtual ~Pool();
   void *allocate(size_t size);
   static Pool *default_pool();   // returns a global pool
};

class Obj_list
{
public:
   inline void *operator new(size_t s, void * p) { return p; }

   Obj_list(const Args *args);
   // when constructed, Obj_list will allocate representation_p, which
   // can take up much more space.

   ~Obj_list();

private:
   Obj_list_store *representation_p;
};

这是聚合。注意会员声明会员列表商店_d:

// Aggregate is derived from Lesser, which is twelve bytes in size
class Aggregate : public Lesser
{
public:
   inline void *operator new(size_t s) {
      return Pool::default_pool->allocate(s);
   }

   inline void *operator new(size_t s, Pool *h) {
      return h->allocate(s);
   }

public:

   Aggregate(const Args *args = NULL);
   virtual ~Aggregate() {};

   inline const Obj_list *member_list_store_p() const;

protected:
   char member_list_store_d[sizeof(Obj_list)];
};

这是我最关心的数据成员。这是初始化和访问的伪代码:

Aggregate::Aggregate(const Args *args)
{
   if (args) {
      new (static_cast<void *>(member_list_store_d)) Obj_list(args);
   }
   else {
      zero_out(member_list_store_d);
   }
}

inline const Obj_list *Aggregate::member_list_store_p() const
{
   return initialized(member_list_store_d) ? (Obj_list *) &member_list_store_d : 0;
}

您可能会建议我们将 char 数组替换为指向Obj_list类型,初始化为 NULL 或类的实例。这给出了正确的语义,但只是改变了内存成本。如果内存仍然非常宝贵(可能是这样,这是 EDA 数据库表示形式),请将 char 数组替换为指向Obj_list在这种情况下会多花费一个指针总计的物体do有会员。

除此之外,我真的不想分散对这里主要问题的注意力,即对齐。我think上述构造是有问题的,但除了对“系统/库”的对齐行为的一些模糊讨论之外,在标准中找不到更多内容new.

那么,上述结构除了导致偶尔的管道停顿之外还有其他作用吗?

Edit: 我意识到有办法replace使用嵌入式 char 数组的方法。最初的建筑师也是如此。他们丢弃了它们,因为内存非常宝贵。现在,如果我有理由接触该代码,我可能会更改它。

然而,我希望人们能够解决我的问题,即这种方法固有的一致性问题。谢谢!


好的 - 有机会正确阅读它。您遇到对齐问题,并且当您将 char 数组作为 Obj_list 访问时会调用未定义的行为。您的平台很可能会执行以下三件事之一:让您摆脱它,让您在运行时惩罚下摆脱它,或者偶尔因总线错误而崩溃。

解决此问题的便携式选项有:

  • 使用 malloc 分配存储空间或 全局分配函数,但是 你也觉得这太 昂贵的。
  • 正如 Arkadiy 所说,让你的缓冲区成为 Obj_list 成员:

    Obj_list list;
    

但你现在不想支付建设成本。您可以通过提供一个内联的不执行任何操作的构造函数来缓解这种情况,该构造函数仅用于创建此实例 - 正如发布的默认构造函数所做的那样。如果您遵循此路线,请强烈考虑调用 dtor

list.~Obj_list();

在将新内容放入此存储之前。

否则,我认为您只剩下不可移植的选项:要么依赖平台对未对齐访问的容忍度,要么使用编译器为您提供的任何不可移植的选项。

免责声明:我完全有可能错过了工会或类似机构的技巧。这是一个不寻常的问题。

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

隐藏在 C++ 类中嵌入 char 数组中的数据成员的性能、安全性和对齐方式是什么? 的相关文章

  • 编译时运算符

    有人可以列出 C 中可用的所有编译时运算符吗 C 中有两个运算符 无论操作数如何 它们的结果始终可以在编译时确定 它们是sizeof 1 and 2 当然 其他运算符的许多特殊用途可以在编译时解决 例如标准中列出的那些整数常量表达式 1 与
  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • 定义 WebActivator.PreApplicationStartMethod 类的初始化顺序

    我有几个 WebActivator PreApplicationStartMethod 装饰类 一个用于 Ninject 另一个用于 AwesomeMVC 第三个用于后台任务调度程序 问题是调度程序类需要利用 IoC 容器解决的依赖关系 我
  • 作用域对象的 Xtext 示例

    我正在寻找一个示例 在 XText 中 说明如何在用户定义的对象成员上实现代码完成 据我所知 我需要使用 IScope 但所有这些如何连接在一起还不清楚 鉴于trait是用户定义的类型 我如何构建语法来编码完成 验证其中包含的方法Strin
  • WordPress URL 中的正斜杠

    我正在将我的网站从 Drupal 迁移到 Wordpress 在 Drupal 中 我可以轻松地给 URL 指定一个别名 这个别名可以是任何东西 即 www example com abc xyz hello html 但在 WordPre
  • 来自两个表的数据而不重复第一个表的数据?

    我的 MySQL 数据库中有两个表 用户表和用户元表 我正在寻找一种方法 通过一个查询从两个表中获取所有信息 但不重复用户表中的信息 这也是与用户 ID 号相关的所有信息 例如 user id 1 有没有办法查询数据库并收集两个表中的所有信
  • 如何从 URL 获取视图中的当前路由 ID (ASP.NET MVC)

    在从 URL 例如 Controller Action 1 返回的视图中 假设默认路由为controller action id 如何从视图中访问 ID 我不想在处理请求时将其添加到操作级别的 ViewData 字典中 我认为这就是您正在寻
  • Crystal Reports 间歇性错误“无法提交请求以进行后台处理。”

    我们在带有 NET Framework 3 5 SP1 的 Windows Server 2008 上运行 Crystal Reports 我见过许多导致一般错误 无法提交请求进行后台处理 的原因 然而 在其他论坛上 由于特定报告的特定格式
  • 两种模板类型和两个模板参数列表有什么区别?

    这两个声明有什么区别 template
  • 如何在自定义服务器控件asp中使用.resx和.resource文件?

    我正在编写自己的服务器端控件 并且使用存储在 resx文件 在控制台应用程序中 此代码运行良好 ResXResourceReader rsxr new ResXResourceReader Resource1 resx foreach Di
  • 将 XML 反序列化为类

    我有正在反序列化的 XML 这是我的 XML
  • 自定义地图标注视图点击即可隐藏

    我已经制作了自定义地图标注 我的标注包含UIButtons and UITextView 当我点击时UIButton 按起来很好 但是当我点击UITextView它将光标移动到点击位置 然后取消选择图钉并消失标注 我已经实施了hitTest
  • Postgres触发器函数更新另一个表中的聚合结果

    我有两张桌子 表 x 和表 y 表 x 每天都会更新 我希望在表 x 中插入新数据后立即更新表 y 表 y 包含表 x 中每天所有更新的聚合值 Date为Date类型 其余两列为real类型 Table x 可以每天更新 table y 应
  • 当url中有空格时htaccess重定向

    我想从仍然出现在谷歌搜索中的旧网址重定向到新网址 旧的网址是这样的 http www marionettecolla org file 20 mostra milano mostra marionette milano htm 我想将其重定
  • 每天在 R 数据帧上应用 cut()

    我在 R 中有一个数据表 我在其中应用了cut and table 我能够根据条件得到频率表 但我得到了总体频率 我想明智地做到这一点 我有一个名为timestamp其中有时间戳 我还有一个section具有价值的列A or B 如何根据每
  • C# 文本文件 - 如何写入 EOF 字符

    这一定是一个简单的问题 但我没有找到任何东西 我有一个文本文件 我需要在末尾放置一个 EOF 字符 以便第三方供应商可以正确读取文件 写入文件结尾字符所需的转义字符是什么 我不确定是否需要提供更多信息 但如果需要 请告诉我 Thanks 如
  • iOS PhoneGap 调试工作流程

    如何在 Xcode 中调试 javascript 我可以做的一件事是在 OS X Chrome 浏览器中打开页面 但这自然不适用于涉及本机代码的应用程序流 我是否缺少一个聪明的 Xcode 技巧 随着 iOS 6 的发布 Apple 与 M
  • 使用 OpenCL 支持构建 OpenCV

    在 CMake 中 我使用 OpenCL Enable ON 构建了 OpenCV 它自动检测到OPENCL INCLUDE DIR路径但是OPENCL LIBRARY即使单击配置后也是空的 为了OPENCL LIBRARY我也没有看到浏览
  • 用于 Cast 对话框的 Android MediaMetaData 图像

    注意到演员对话框中有一些奇怪的东西 使用 MediaInfo Builder 为调用 RemoteMediaClient load mediainfo 准备 MediaInfo 如果这次 MediaMetaData addImage 使用与
  • gcc 预编译头使用 -c 选项时出现奇怪的行为

    短篇故事 我无法使用 gcc c 选项使预编译头正常工作 很长的故事 各位 我在 Linux 上使用 gcc 4 4 1 在一个非常大的项目中尝试预编译头之前 我决定在简单的程序上测试它们 他们 有点工作 但我对结果不满意 我确信我的设置有
  • 是否可以根据 Accept 标头的媒体类型在 .NET MVC 中选择具有 AttributeRouting 的操作?

    我想根据 Accept 标头中请求的媒体类型选择控制器的操作 例如 我有一个称为主题的资源 其指定路线为 GET subjects subjectId int 一般情况下 浏览器会请求text html 这很好 默认的媒体格式化程序可以很好
  • 隐藏在 C++ 类中嵌入 char 数组中的数据成员的性能、安全性和对齐方式是什么?

    我最近看到一个代码库 我担心它违反了对齐约束 我已经对其进行了擦洗 以生成一个最小的示例 如下所示 简而言之 球员们是 Pool 对于 高效 的某些定义 这是一个有效分配内存的类 Pool保证返回一块与请求大小对齐的内存块 Obj list