- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所有,我有一个关于 C 中数组的内存对齐的有趣问题。我的操作系统是 32 位 Ubuntu,我使用 gcc -S -fno-stack-protector 选项编译它。
代码:
char array1[5] = "aaaaa";
char array2[8];
array2[0] = 'b';
pushl %ebp
move %esp, %ebp. # esp and ebp are pointing to the same words
subl $16, %esp # move esp to lower 16
movl $1633771873, -5(%ebp) # input "aaaa"
movb $97, -1(%ebp). # input 'a'
movb $98, -13(%ebp) # input 'b'
movl $0, %eax
leave
%ebp
是
efe8
,
%esp
是
efd8
,
&buf1
是
efe3
,
&buf2
是
efdb
.
x/4bd 0xbfffefd8
, 表明
0xbfffefd8: 9 -124 4 98
0xbfffefd8: 9
0xbfffefd8: 98
## high address ##
? efe8 <-- ebb
97 97 97 97 efe4
0 -80 -5 97(a) efe0
0 0 0 0 efdc
9 -124 4 98(b) efd8 <-- esp
^ ^
| |
efd8 efdb
efdb
, 而 %esp
是 efd8
?我认为 'b' 也应该在 efd8
,因为它是 4 字节字的开始。此外,如果我继续向 buf2
填充更多“b”从 efdb
开始,它只能填5'b',不能填8。怎么会? '\0' 呢? buf1
, 从
efe3
开始,不是
efe0
.这是一种什么样的对齐方式?这对我来说没有意义。
andl $-16, %esp # this aligns esp to 16 boundary
char[5]
不被解释为考虑内存对齐的方式。那么内存对齐应该发生在运行时。我对吗?但是 GDB 调试显示与汇编代码完全相同。根本没有对齐。
最佳答案
我看这里没有任何问题。 TLDR 答案:char 数组对齐到 1 个字节 ,编译器是对的。
再挖一点。在我的 64 位机器上,使用带有 -m32 选项的 GCC 7,我运行和调试了相同的代码,我得到了相同的结果:
(gdb) x/4bd $esp+12
0xffffcdd4: 97 97 97 97
(gdb) x/4bd $esp+8
0xffffcdd0: 0 -48 -7 97
(gdb) x/4bd $esp+4
0xffffcdcc: 0 0 0 0
(gdb) x/4bd $esp+0
0xffffcdc8: 41 85 85 98
$esp
, 以 4 字节对齐,正如预期的那样:
(gdb) p $esp
$9 = (void *) 0xffffcdc8
array1[5]
并将其放在堆栈上,但由于它是 5 个字节宽,因此将其扩展为第二个双字。因此,第一个 dword 充满了“a”,而仅使用了第二个 dword 的 1 个字节。现在,
array2[8]
紧随其后(或之前,取决于您的外观)
array1[5]
.它在 3 个双字上扩展,以
$esp
指向的双字结尾.
[esp + 0] <3 bytes of garbage /* no var */>, 'b' /* array2 */,
[esp + 4] 0x0, 0x0, 0x0, 0x0, /* still array2 */
[esp + 8] <3 bytes of garbage /* still array2 */>, 'a' /* array1 */,
[esp + 12] 'a', 'a', 'a', 'a', /* still array1 */.
char[2]
array2
之后的数组您将使用
$esp
指向的相同双字看到它并且仍然有来自
$esp
的 1 个字节的垃圾给您的
array3[2]
.
char
数组要以 4 字节对齐(但您需要一个很好的理由!),您必须使用特殊的编译器属性,例如:
__attribute__ ((aligned(4)))
关于C语言 : how memory alignment happened in the stack for array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59865199/
我们有一些第三方代码,它们执行以下操作 列表项 创建用户交易,例如 txn = (UserTransaction)ctx.lookup( "UserTransaction" ); txn.begi
表达式 "a".(strlen('ab')-strlen('a')) 按预期计算为 a1。 但是如果我不小心省略了括号, "a".strlen('ab')-strlen('a') 计算结果为-1。这里
我读到了有关 Java 类型删除的内容 on Oracle's website . 什么时候发生类型删除?在编译时还是运行时?类什么时候加载?类何时实例化? 很多网站(包括上面提到的官方教程)都说
我读到了有关 Java 类型删除的内容 on Oracle's website . 什么时候发生类型删除?在编译时还是运行时?类什么时候加载?类何时实例化? 很多网站(包括上面提到的官方教程)都说
我试图对 Haskell 中类型族“发生”的类型级计算何时(以及多少次)形成一种直觉。对于一个具体的例子,考虑这个类型类来索引到 n-ary product使用类型级自然: {-# LANGUAGE
我正在阅读 Java Concurrency in Practice书。 在阅读关于 JMM 的章节时,它说: The JMM defines a partial ordering called ha
我读到了 Java 的类型删除 on Oracle's website . 类型删除何时发生?在编译时还是运行时?什么时候加载类?什么时候实例化类? 很多网站(包括上面提到的官方教程)都说类型删除发生
我一周前通过互联网向 Apple 申请加入 Iphone 开发计划,并向他们发送了我的 99.00 美元。 我的印象是,总的来说,响应速度很快。然而,除了一封确认我购买的电子邮件之外,我什么也没看到。
我读到了 Java 的类型删除 on Oracle's website . 什么时候发生类型删除? 在编译时还是运行时?什么时候加载类?什么时候实例化类? 很多网站(包括上面提到的官方教程)都说类型删
我读到了 Java 的类型删除 on Oracle's website . 类型删除何时发生?在编译时还是运行时?什么时候加载类?什么时候实例化类? 很多网站(包括上面提到的官方教程)都说类型删除发生
有一个快速同步问题,这是我的: a) Class1 的并发 HashMap 定义如下: ConcurrentMap map = new ConcurrentHashMap(); b) Class2
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我正在研究 Java 并发性并找到了以下资源以供引用, http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-su
我根据Douglas Crockford在他的书“Javascript: the good parts”中提出的布局创建了一个对象构造函数。 此构造函数在添加各种成员和方法后返回一个 that 对象。
我正在编写一个单元测试(在 Mocha 中使用 Chai)来查看某个对象 o 是否是 instanceof ClassY。单元测试成功,但我可以让它失败,具体取决于我如何创建对象文字,尽管生成的对象文
假设我有一个包装 HashMap 的类,如下所示: public final class MyClass{ private final Map map; //Called by T
我想弄清楚 happens-before 属性的确切含义。 我看到 happens-before 属性的解释说,如果全局变量(不是易变的或包含在同步块(synchronized block)中)的更新
虽然在 SO 和其他地方有很多关于 happens-before 关系的帖子,但我很难找到我的问题的明确答案。 考虑两个 Java 线程: 最初,flag == false 和 data == 0 T
http://coliru.stacked-crooked.com/a/c795a5d2bb91ae32 #include struct X { X(const char *) { std:
我读到了 Java 的类型删除 on Oracle's website . 类型删除何时发生?在编译时还是运行时?什么时候加载类?什么时候实例化类? 很多网站(包括上面提到的官方教程)都说类型删除发生
我是一名优秀的程序员,十分优秀!