问题标签 [memory-alignment]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 了解堆栈分配和对齐
我试图了解堆栈对齐是如何工作的,如什么是“堆栈对齐”中所述?但我很难找到一个小例子来证明上述行为。我正在检查我的函数 foo 的堆栈分配:
我用(即没有任何编译器标志)编译了源文件,gcc -ggdb example.c -o example.out
并且来自 gdb 的汇编程序转储读取:
我的堆栈以 16 个字节的块分配(我用其他几个测试验证了这一点)。根据此处的汇编程序转储,已分配 32 个字节,因为 (16 < 4+16 < 32),但是我希望在前 16 个字节上分配整数“a”,然后在接下来的 16 个字节上分配字符数组(中间留出 12 个字节的空间)。但似乎整数和字符数组都被分配了一个 20 字节的连续块,根据我上面提到的讨论,这是低效的。有人可以解释一下我在这里缺少什么吗?
编辑:我得出的结论是,我的堆栈被分配为 16 个字节的块,程序如下:
以及相应的汇编转储:
您可以看到堆栈上已为大小为 1 的字符数组分配了 16 个字节(仅需要 1 个字节)。我可以将数组的大小增加到 16 并且汇编程序转储保持不变,但是当它为 17 时,它会在堆栈上分配 32 个字节。我已经运行了很多这样的样本,结果是一样的;堆栈内存以 16 字节的块分配。在堆栈分配、填充和对齐中讨论了一个类似的主题,但我更想知道的是为什么对齐在我的示例中没有效果。
c - GCC 隐式对齐问题。(64 位代码)
如何在 gcc 中明确禁用已定义变量的对齐?
拿这个代码:
这将定义一个大小为 24 字节的结构。
我试着做:
所以
&memstrx[0]
应该有一个值 0x502
&memstrx[1]
, 0x51A
&memstrx[2]
, 0x532
...等等等等。
但事情似乎不太对劲。
相反,
&memstrx[1]
, 显示地址 0x522
&memstrx[2]
, 0x542
&memstrx[3]
, 0x552
... 等等等等。
我怀疑 GCC 已经隐式地将结构重新调整为 32 字节(从 24 字节),强制(每个条目的 64 位对齐)。而且我真的不希望这种行为只针对这种结构。我应该如何告诉 GCC 不对齐该结构?
c++ - C++ 中的原子性:神话还是现实
我一直在阅读MSDN中有关无锁编程的文章。它说 :
在所有现代处理器上,您可以假设 自然对齐的本机类型的读取和写入是原子的。只要内存总线至少与正在读取或写入的类型一样宽,CPU 在单个总线事务中读取和写入这些类型,使得其他线程无法看到它们处于半完成状态。
它给出了一些例子:
我读了很多答案和评论说,在 C++ 中没有任何东西可以保证是原子的,甚至在标准中都没有提到它,在 SO 中,现在我有点困惑。我误解了这篇文章吗?还是文章作者谈论的是非标准的和特定于 MSVC++ 编译器的东西?
所以根据文章,下面的任务必须是原子的,对吧?
如果是真的,替换Name[5]
和pad3[3]
对std::string Name;
内存对齐有什么影响吗?Number2
对变量和变量的赋值Value
仍然是原子的吗?
有人可以解释一下吗?
c++ - std::map 节点对齐
我正面临着一件非常了不起的事情。(场景:Win7 pro 64位,VC2008编译32位代码)
假设一个主程序实例化一个使用 std::map 的类。
这是一个 std::map<std::string,Props> 类 Props 只有两个成员:
现在...我构建了一个 DLL,为它自己的业务使用相同的类。
DLL 实例化该类并提供 std::map。
嗯...当主程序提供地图时一切正常,而 DLL 在第一个项目插入后崩溃。
更多(非常有趣)的东西。
如果我深入到由主程序完成的插入,我将单个 _Node 的构造函数放入 std::map
_Node 显示如下(c:\Programmi\Microsoft Visual Studio 9.0\VC\include\xtree)
很好……所以我们的 _Node 结构有 _Left(4 字节)、_Parent(4 字节)、_Right(4 字节)、_Myval(地图的键和值的大小)、_Color(1 字节)和 _Isnil(1 字节)。
现在...我要为地图提供的元素是一对 <std::string, Props>。
根据我的调试器,std::string 需要 0x20 个字节,而 Props 只需要 8 个。
现在,当我询问调试器单个节点的大小时,我可以看到它是 0x38。所以...0x4 + 0x4 + 0x4 + 0x20 + 0x8 + 0x1 + 0x1 = 0x36 + 填充 = 0x38。
这意味着 _Color 成员在 _Node 开始后的 0x34 字节处开始。
(好吧...我宁愿指定我所有的项目都使用 /Zp4 所以所有结构都是 4 字节打包)。
让我们继续...当我遵循 DLL 行为时,我可以看到一些非常惊人的东西。
std::map 的 _Buynode() 方法调用分配器为我要插入的新元素设置新的大小。调用分配器而不是调用 _Node() 就地构造函数....并且它以另一种方式起作用!!
在这种情况下,构造函数表现为 _Color 成员在 _Node 开头的 0x38 字节之后开始......好像有不同的填充一样。
在此之后,在以下尝试插入新值时,该过程失败,因为 _Color 和 _Isnil 的值......错误(0xcc,因为该部分内存未初始化)。
我确定我在所有项目中都将 /Zp4 设置为解决方案,所以......
怎么了?
我“感觉”对齐有问题,但我不能说什么......
提前致谢!
好的...我要添加更多内容。
这是来自 c:\Programmi\Microsoft Visual Studio 9.0\VC\include\xtree 的 _Node 结构
如您所见,它的构造函数非常简单。
当我按照我之前所说的那样查找 std::map 时,查看从这个结构中使用的内存。
- _Left
4 个字节 - _Parent 4 个字节 - _Right
4 个字节
- _Myval 0x28 个字节(std::string 为 0x20,我自己的类为 8 个。我检查过,它总是 8 个字节)
- _Color 1 个字节
- 1 _Isnil 的字节
当一个新元素放置在树的顶部(我的意思是最左边的)被创建时,这个 costructor 填充 _Left、_Parent、_Right、_Myval,而不是 lat 4 个未初始化的字节(比如填充 0xcc)并填充它认为应该是 _Color和 _Isnil 提前 4 个字节。
最荒谬的是 std::map 的其他方法不会“感觉”这 4 个字节。
这些是导致 de 断言的行。
发生这种情况是因为对 _IsNil(_Ptr) 的测试发现 _Isnil 为 0xcc,并给出了错误。发布版本可能不疯,这不是一件快乐的事。
任何想法?
又一步!
我把整个解决方案(2个大项目,18个小项目,大约250000个C/C++代码行),在Linux下编译(gcc4.1.2)。
一切都很好。完全没有问题,std::map 可以正常工作。
我不得不说 Linux Makefile 同时让一切变得更加简单和复杂。复杂是因为你必须自己做所有事情,简单是因为如果你不想做就什么都不会发生。
这告诉我一件事:Visual Studio 2008 中存在一些问题,在某些特定条件下会跳到舞台上……问题是“导致这种情况的条件是什么?”。
等待一个想法...
visual-c++ - Visual C++ 中的类型默认对齐方式
刚刚注意到一些对我来说很奇怪的东西。默认情况下,Visual C++ 不会将对象对齐在其所需的边界中。例如 long long 与 4 字节边界对齐,而 __alignof(T) 返回 8(据我所知,它总是返回类型的大小)。所以看起来它没有正确对齐。例如
我还尝试仅打印指针,其值为&a2
(0x0035F8FC
以3537148
dec 为单位)。
有什么我错了吗?我需要正确对齐的 long long 类型的对象。我能做些什么呢?我可以使用__declspec(align())
微软扩展,但它需要文字数字,所以我不能写这样的东西。
c - 为什么结构必须是字对齐的?
可能重复:
内存对齐的目的
为什么结构或任何内存分配(如 int,char)必须是字对齐的。它有什么优势?
更新:主要原因是,如果不是内存对齐,有可能数据类型(int)的一部分在一个物理页面中,而另一部分在另一个物理页面中?
我觉得这是一个更强有力的理由?
c++ - 给定数据类型的字节对齐要求是否保证为 2 的幂?
给定数据类型的字节对齐要求是否保证为 2 的幂?
除了“没有意义”之外,还有什么东西可以提供这种保证,因为它与系统页面大小不符?
(背景:C/C++,所以随意假设数据类型是 C 或 C++ 类型并给出 C/C++ 特定的答案。)
c++ - SSE 和 C++ 容器
以下代码段错误是否有明显的原因?
谢谢
编辑:我在 linux/i686 上使用 g++ 4.5.0,我可能不知道我在这里做什么,但因为即使是以下段错误
我真的认为这一定是和对齐问题。
java - Java内存分配对齐
我知道在 Java 中这是一个奇怪的问题,但是有没有办法让 Java 动态内存分配与一些对齐约束对齐?例如,是否可以动态分配与页面大小对齐的对象?
我之所以要这样做,是因为我要通过JNI接口从native代码访问Java对象,而native代码库要求对象对齐。
谢谢。
c++ - 引用静态对象 - 在 ARM proc 上触发对齐陷阱
我有一堂课:
我在 ARM 处理器上运行它。我遇到的问题是,当我从特定类(比如 B 类)调用 instance() 方法时,应用程序会触发内核中的对齐陷阱。如果我从其他任何地方调用 instance(),我不会遇到对齐陷阱。
对齐陷阱:未处理 [<0001b588>] 处的指令 e28fc609
如果我将指针转换为未对齐的值,我可以看到会发生这种情况,但我只是引用一个静态对象。有人会假设访问会正确对齐。
请注意,该类被大大简化了。它包含很多成员变量和方法(不是我的设计!)。
有人对我可能出错的地方或去哪里有任何建议吗?