gpt4 book ai didi

c++ - 使用虚拟继承的未对齐地址

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:33:28 24 4
gpt4 key购买 nike

以下看似有效的代码使用 UndefinedBehaviorSanitizer sanitizer 产生了未对齐的地址运行时错误。

#include <memory>
#include <functional>

struct A{
std::function<void()> data; // seems to occur only if data is a std::function
} ;

struct B{
char data; // occurs only if B contains a member variable
};

struct C:public virtual A,public B{

};

struct D:public virtual C{

};

void test(){
std::make_shared<D>();
}

int main(){
test();
return 0;
}

在 macbook 上编译和执行clang++ -fsanitize=undefined --std=c++11 ./test.cpp && ./a.out产生输出运行时错误:构造函数调用类型“C”的未对齐地址 0x7fe584500028,这需要 16 字节对齐 [...]

我想了解错误发生的方式和原因。

最佳答案

std::function<void()> 对齐以来是 16,大小是 48 让我们简化。此代码具有 same behavior但更容易理解:

struct alignas(16) A
{ char data[48]; };

struct B
{ char data; };

struct C : public virtual A, public B
{};

struct D : public virtual C
{};

int main()
{
D();
}

我们有以下对齐方式和尺寸:

                     |__A__|__B__|__C__|__D__|
alignment (bytes): | 16 | 1 | 16 | 16 |
size (bytes): | 48 | 1 | 64 | 80 |

现在让我们看看它在内存中的样子。可以在 this great answer 中找到更多解释。 .

  • 答: char[48] + no padding == 48B
  • 乙: char[1] + no padding == 1B
  • C: A* + B + A + 7 bytes of padding (align to 16) == 64B
  • D: C* + C + 8 bytes of padding (align to 16) == 80B

现在很容易看出C的偏移量里面D是 8 个字节,但是 C对齐到 16。因此错误,这个伪图形很有帮助

00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
^

这里每个零是1个字节。

更新:在哪里以及如何放置填充取决于 C++ 编译器。标准没有规定。看起来它具有的填充大小,clang 无法对齐 D 中的所有内容.减轻错位的一种方法是仔细设计您的类,使它们具有相同的对齐方式(例如,8 字节)。

关于c++ - 使用虚拟继承的未对齐地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46474238/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com