什么是在内存中表示的未定义的向量元素?



我目前正在学习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 至少是零填充其余部分。 但是正如评论中指出的那样,您应该看到规范,仅仅因为一个编译器没有,这并不意味着这就是它应该工作或总是工作的方式。

最新更新