Questions tagged «memory-layout»

3
C中的结构内存布局
我有C#背景。我是C之类的底层语言的新手。 在C#中,struct默认情况下,的内存由编译器布置。编译器可以重新排序数据字段或隐式填充字段之间的其他位。因此,我必须指定一些特殊属性来覆盖此行为,以实现准确的布局。 AFAIK,C在struct默认情况下不会重新排序或对齐的内存布局。但是,我听说很难找到一个例外。 C的内存布局行为是什么?什么应该重新排序/对齐而不是?

7
指针比较在C中如何工作?比较不指向同一数组的指针是否可以?
在K&R(C编程语言第二版)第5章中,我阅读了以下内容: 首先,可以在某些情况下比较指针。如果p和q指向同一个数组的成员,则关系一样==,!=,<,>=,等正常工作。 这似乎暗示着只能比较指向同一数组的指针。 但是当我尝试这段代码时 char t = 't'; char *pt = &t; char x = 'x'; char *px = &x; printf("%d\n", pt > px); 1 被打印到屏幕上。 首先,我以为我会得到未定义或某种类型或错误的信息,因为pt和px没有指向同一数组(至少在我看来)。 同样是pt > px因为两个指针都指向存储在堆栈中的变量,并且堆栈变小,所以的内存地址t大于x?的内存地址。这是为什么pt > px呢? 引入malloc时,我会更加困惑。同样,在K&R的8.7章中,内容如下: 但是,仍然有一个假设,即sbrk可以有意义地比较指向返回的不同块的指针。该标准不能保证这一点,该标准仅允许在数组内进行指针比较。因此,此版本malloc仅可在通用指针比较有意义的机器之间移植。 将指向堆上分配的空间的指针与指向堆栈变量的指针进行比较,我没有任何问题。 例如,以下代码可以很好地工作并1可以打印: char t = 't'; char *pt = &t; char *px = malloc(10); strcpy(px, pt); …

2
[[no_unique_address]]和两个相同类型的成员值
我玩弄[[no_unique_address]]在c++20。 在cppreference的示例中,我们有一个空类型Empty和Z struct Empty {}; // empty class struct Z { char c; [[no_unique_address]] Empty e1, e2; }; 显然,的大小Z至少必须是2因为e1和的类型e2相同。 但是,我真的很想拥有Zsize 1。这让我开始思考,如何Empty在包装类中使用额外的模板参数来包装,这些模板参数会强制执行e1和类型的不同e2。 template <typename T, int i> struct Wrapper : public T{}; struct Z1 { char c; [[no_unique_address]] Wrapper<Empty,1> e1; [[no_unique_address]] Wrapper<Empty,2> e2; }; 不幸的是,sizeof(Z1)==2。是否有使大小Z1成为一体的技巧? 我有测试此gcc version 9.2.1与clang version 9.0.0 在我的应用程序中,我有很多空类型的表格 …

1
当空基类也是成员变量时,为什么禁止空基优化?
空基优化非常棒。但是,它具有以下限制: 如果空基类之一也是第一个非静态数据成员的类型或类型的基,则禁止空基优化,因为相同类型的两个基子对象需要在对象表示中具有不同的地址最派生的类型。 要解释此限制,请考虑以下代码。该static_assert会失败。而将Foo或更改为或Bar从继承Base2将避免错误: #include <cstddef> struct Base {}; struct Base2 {}; struct Foo : Base {}; struct Bar : Base { Foo foo; }; static_assert(offsetof(Bar,foo)==0,"Error!"); 我完全了解这种行为。我不明白的是为什么存在这种特殊行为。显然添加它是有原因的,因为它是显式添加,而不是疏忽。这样做的理由是什么? 特别是为什么要要求两个基本子对象具有不同的地址?在上面,Bar是一个类型,并且foo是该类型的成员变量。我看不出为什么基类对Bar类型为的基类很重要foo,反之亦然。 确实,如果有的话,我希望它&foo与Bar包含它的实例的地址相同,因为在其他情况下它是必需的(1)。毕竟,我对virtual继承没有任何幻想,无论如何基类都是空的,并且带有的编译Base2显示在这种特殊情况下没有任何中断。 但是显然,这种推理在某种程度上是不正确的,并且在其他情况下,也需要这种限制。 假设答案应该针对C ++ 11或更高版本(我目前正在使用C ++ 17)。 (1)注意:EBO在C ++ 11中进行了升级,并且特别成为StandardLayoutTypes的必需项(尽管Bar,上面不是StandardLayoutType)。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.