我目前正在学习C,我有一个问题,我必须猜测内存中的值。 例如,当我说long var1[1243] = {10, 1, 0, -1, -10}
并定义这个向量时,它的前 5 个元素已经定义,但是代表剩余 1238 个元素的分配字节,它们在内存中设置了什么?更具体地说,它们是 0 吗?在组装中,在定义它们之后,说.zero <number of remaining bytes in vector>
正确吗?
通过至少初始化一些元素{10}
C 将初始化数组中的所有剩余元素,就像全局变量一样。数字零或空指针取决于类型,对于结构数组,则递归地显示结构的所有成员。
在C++中,空的初始值设定项也可以long var1[1243] = {}
,但这在C中是不允许的。
为什么不试试呢?
long var1[1243] = {10, 1, 0, -1, -10};
long so ( unsigned int x )
{
long var2[1243] = {10, 1, 0, -1, -10};
return(var2[x]);
}
编译和反汇编
Disassembly of section .text:
00000000 <so>:
0: e92d4010 push {r4, lr}
4: e24ddd4d sub sp, sp, #4928 ; 0x1340
8: e24dd030 sub sp, sp, #48 ; 0x30
c: e1a04000 mov r4, r0
10: e3a01000 mov r1, #0
14: e59f203c ldr r2, [pc, #60] ; 58 <so+0x58>
18: e28d0004 add r0, sp, #4
1c: ebfffffe bl 0 <memset>
20: e3a0000a mov r0, #10
24: e3a01001 mov r1, #1
28: e3e02000 mvn r2, #0
2c: e3e03009 mvn r3, #9
30: e98d0003 stmib sp, {r0, r1}
34: e58d3014 str r3, [sp, #20]
38: e58d2010 str r2, [sp, #16]
3c: e28d3e37 add r3, sp, #880 ; 0x370
40: e0830104 add r0, r3, r4, lsl #2
44: e510036c ldr r0, [r0, #-876] ; 0xfffffc94
48: e28ddd4d add sp, sp, #4928 ; 0x1340
4c: e28dd030 add sp, sp, #48 ; 0x30
50: e8bd4010 pop {r4, lr}
54: e12fff1e bx lr
58: 0000136c andeq r1, r0, r12, ror #6
Disassembly of section .data:
00000000 <var1>:
0: 0000000a andeq r0, r0, r10
4: 00000001 andeq r0, r0, r1
8: 00000000 andeq r0, r0, r0
c: ffffffff ; <UNDEFINED> instruction: 0xffffffff
10: fffffff6 ; <UNDEFINED> instruction: 0xfffffff6
...
要确认...如果我链接它,那么我在 .data 中看到零:
00000000 10 40 2d e9 4d dd 4d e2 30 d0 4d e2 00 40 a0 e1 |.@-.M.M.0.M..@..|
00000010 00 10 a0 e3 3c 20 9f e5 04 00 8d e2 0e 00 00 eb |....< ..........|
00000020 0a 00 a0 e3 01 10 a0 e3 00 20 e0 e3 09 30 e0 e3 |......... ...0..|
00000030 03 00 8d e9 14 30 8d e5 10 20 8d e5 37 3e 8d e2 |.....0... ..7>..|
00000040 04 01 83 e0 6c 03 10 e5 4d dd 8d e2 30 d0 8d e2 |....l...M...0...|
00000050 10 40 bd e8 1e ff 2f e1 6c 13 00 00 1e ff 2f e1 |.@..../.l...../.|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000 0a 00 00 00 01 00 00 00 00 00 00 00 ff ff ff ff |................|
00001010 f6 ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
0000236c
因此,对于本地和全局版本,gcc 至少是零填充其余部分。 但是正如评论中指出的那样,您应该看到规范,仅仅因为一个编译器没有,这并不意味着这就是它应该工作或总是工作的方式。