使用较小的默认对齐方式重载 new 运算符

2023-11-24

C++17 引入过度对齐数据的动态内存分配

除了现有的std::max_align_t,基本对齐,它补充说__STDCPP_DEFAULT_NEW_ALIGNMENT__运算符 new 保证的最小对齐。

通过 MSVC2017 64 位编译,这些常量会产生std::max_align_t尺寸为 8 且__STDCPP_DEFAULT_NEW_ALIGNMENT__尺寸为 16。

然而,它可以否决运算符 new/free,如上所述cppreference:operator new - 全局替换.

查看所有文档,我不清楚是否允许该函数提供新的默认对齐方式,如果可以,是否允许我们重新定义该常量。

举例说明:

#include <new>
#include <iostream>
#include <cassert>
#include <cstdint>
#include <cstddef>

static_assert(alignof(std::max_align_t) == 8);
static_assert(__STDCPP_DEFAULT_NEW_ALIGNMENT__ == 16);


void * operator new(size_t size) 
{ 
    std::cout << "New operator overloading " << std::endl; 
    void * p = std::malloc((size == 8) ? 16 : size); 
    assert(std::uintptr_t(p)%16 == 0);
    if (size == 8)
        {
        auto correctedPtr = std::uintptr_t(p) + 8;
        return (void*)correctedPtr;
        }
    return p; 
} 

void operator delete(void * p) 
{ 
    std::cout << "Delete operator overloading " << std::endl; 
    if (std::uintptr_t(p)%16 != 0)
    {
        auto correctedPtr = std::uintptr_t(p) - 8;
        std::free((void*)correctedPtr);
    }
    std::free(p); 
}

namespace
{
    struct D
    {
        double d;
    };
}


int main(int, char**)
{
    new D{};
    return 0;
}

编译器资源管理器中的代码

我之所以问这个问题,是因为我正在调查正在使用 Clang 编译的 MSVC 程序中的崩溃情况。这里我们注意到 clang 使用依赖于 16 位对齐的 CPU 指令来初始化大小为 8 的类。


根据N4659(C++17 的最新公开草案):

6.7.4p3:

C++ 程序中定义的任何分配和/或释放函数, 包括库中的默认版本,应符合 6.7.4.1 和 6.7.4.2 中指定的语义。

6.7.4.1p2:

...返回的指针应适当对齐,以便可以 转换为指向任何合适的完整对象类型的指针(21.6.2.1) 然后用于访问存储中的对象或数组 已分配(直到通过调用显式释放存储 相应的释放函数)。 ...

19.8p1:

以下宏名称应由实现定义: ...__STDCPP_DEFAULT_NEW_ALIGNMENT__std::size_t 类型的整数文字,其值是通过调用保证的对齐operator new(std::size_t) or operator new[](std::size_t). ...

19.8p4:

如果本子条款中的任何预定义宏名称,或 标识符defined, 是一个主题#define or a #undef预处理指令,行为未定义。 ...

因此,您无法更改__STDCPP_DEFAULT_NEW_ALIGNMENT__程序内的值,以及如果调用分配函数alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__)大小为 8 的类型,您无法检测到这一点,但您仍然需要返回一个适当对齐的指针。

尽管如此,您可以更改__STDCPP_DEFAULT_NEW_ALIGNMENT__由 clang 本身定义的值-fnew-alignment编译器选项。不确定它对您的情况是否有帮助。

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

使用较小的默认对齐方式重载 new 运算符 的相关文章

随机推荐

  • 判断一个数是否是斐波那契数

    我需要编写一段Java代码来检查用户输入的数字是否在斐波那契数列中 我在将斐波那契数列写入输出时没有任何问题 但是 可能是因为已经是深夜了 我正在努力思考 是否 是斐波那契数列 我不断地一遍又一遍地开始 这真的让我很头疼 我目前拥有的是第n
  • 从 C 调用 FORTRAN 子例程

    我正在尝试从 C 调用 FORTRAN 函数 我的问题是 If fortRoutine是我的 Fortran 子例程的名称 那么我从 C 调用它 作为fortRoutine If fortRoutine仅包含一个字符数组参数 那么我可以这样
  • 山狮升级后无法安装某些宝石

    我刚刚将我的 Macbook 更新为 Mountain Lion 但现在我无法安装一些 gem 因为出现以下有关标头的错误 我环顾四周 这似乎与缺少 Ruby 标头有关 建议安装 Xcode 因此我从应用商店安装了完整的 Xcode 以及
  • android 两个应用程序之间的通信

    我需要一些帮助来开始开发两个相互通信的 Android 应用程序 在一部手机上 应用程序 A 向应用程序 B 发送字符串 应用程序 B 接收字符串 例如 startClassOne 应用程序 B 使用方法启动 classOne 并获取结果
  • 如何制作不区分大小写的ConcurrentMap?

    我该如何实施 class CaseInsensitiveConcurrentMap
  • 获取 2 个字符串之间的字符串

    如何获取位于两个其他声明的字符串之间的字符串 例如 String 1 STRING1 String 2 STRING2 Source 832h0ufhu0sdf4 STRING1 I need this text here STRING2
  • 你能以 O(n) 摊余复杂度对 n 个整数进行排序吗?

    理论上是否可以以 O n 的摊余复杂度对 n 个整数的数组进行排序 尝试创建 O n 复杂度的最坏情况怎么样 现在的大多数算法都是建立在平均 O nlogn 最坏情况 O n 2 之上 有些虽然使用更多内存 但最糟糕的是 O nlogn 你
  • 无法加载捆绑包中的 NIB

    我正在尝试将 Janrain Engage 作为自定义模块与 Appcelerator Titanium 集成 我创建了一个示例模块 并将 JREngage 文件夹拖到示例模块 xcodeproj 如 Jainrain 文档中所示 现在我给
  • Python 和 R 之间的线性回归系数之间的差异

    我正在尝试在 Python 中运行我已经在 R 中完成的线性回归 以便找到系数为 0 的变量 我遇到的问题是 R 中的线性回归返回低方差列的 NA 而 scikit learn 回归返回系数 在 R 代码中 我通过将带有 NA 的变量保存为
  • 从 python selenium 测试中制作 exe 文件

    我尝试在 exe 文件中构建 python selenium 测试 并在许多机器上运行它 以保持测试独立于环境 但结果 exe 文件找不到 selenium webdriver 如何在 exe 文件中包含所有硒依赖项 或者也许还有其他方法吗
  • 尝试将 R.exe 添加到 PATH

    所以我尝试将 R 添加到 Windows 10 上的路径 这应该很简单 System Properties gt Environment variables gt Edit gt new copy and paste C Program F
  • 为什么单击文本框会导致自动滚动面板滚动回顶部?

    在 C 应用程序中完成注册表单时 我注意到 如果我启用自动滚动 然后在滚动条下方有一个文本框 然后单击它 它会一直跳回到顶部 有没有办法用一些代码来解决这个问题 或者这是一个专有名词 对我来说用语言解释有点困难 所以这里是一个短视频这表明了
  • “shutdown -y”到底是做什么的? [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我在之后尝试了一些随机参数shutdown当我偶然发现 PowerShell 2 0 中的命令时shutdown y 所有这一切seems要做的就是注销用户 如果使用任何其他随机字母
  • python 中的泛型/模板?

    python 如何处理泛型 模板类型场景 假设我想创建一个外部文件 BinaryTree py 并让它处理二叉树 但适用于任何数据类型 所以我可以将自定义对象的类型传递给它 并拥有该对象的二叉树 这是如何在 python 中完成的 其他答案
  • 更改图钉颜色 MKMapView

    我以这种方式向地图添加注释 MyAnnotation annotationPoint2 MyAnnotation alloc init annotationPoint2 coordinate anyLocation annotationPo
  • 在运行时创建继承抽象类并实现接口的类型

    我们的架构广泛使用存储库模式 我们为大多数存储库提供了一个抽象基类 它实现了一些常见的功能 例如获取 加载 列表等 这个基类有一个对应的接口IRepository 它定义了抽象类的公共方法 大多数实体都有对应的存储库接口 例如Foo 实体有
  • .htaccess 将根目录重定向到index.php

    我需要重定向自http example com to http example com index php 用这个 DirectoryIndex index php
  • 使用 GCC 查找无法访问的函数(“死代码”)

    我正在寻找一种在 非常 大型 C 项目中查找静态无法访问的函数的方法 我曾尝试使用 doxygen 和此处建议的其他静态分析工具 但似乎该项目太复杂 他们无法处理 最后我决定使用 GCC 工具 g gprof gcov 等 是最安全的选择
  • Flutter 中的元素是什么?

    我很难理解 Flutter 中的元素是什么 来自文档 树中特定位置的小部件的实例化 我想现在我必须问 那棵树是什么 起初 我以为树指的是小部件的状态 但 StatelessWidget 也有 createElement 所以情况似乎并非如此
  • 使用较小的默认对齐方式重载 new 运算符

    C 17 引入过度对齐数据的动态内存分配 除了现有的std max align t 基本对齐 它补充说 STDCPP DEFAULT NEW ALIGNMENT 运算符 new 保证的最小对齐 通过 MSVC2017 64 位编译 这些常量