为什么我的函数局部变量之间在堆栈中没有存储空间?

顽固

我在Ubuntu x86上使用gcc编译了一个C程序。这是我正在从中调用的函数main

void addme()
{
  long a = 5;
  char c = '3';
  long array[3];
  array[0] = 2;
  array[1] = 4;
  array[2] = 8;
}

如果我在最后一行中断,并进行调试/检查,这就是我得到的

(gdb) print &a
$5 = (long *) 0xbffff04c
(gdb) print &c
$6 = 0xbffff04b "3\005"
(gdb) print &array
$7 = (long (*)[3]) 0xbffff03c
(gdb) x 0xbffff03c
0xbffff03c:     0x00000002
(gdb) x 0xbffff040
0xbffff040:     0x00000004
(gdb) x 0xbffff044
0xbffff044:     0x00000008
(gdb) x 0xbffff04c
0xbffff04c:     0x00000005

c当只需要0xbffff04b来存储char,为什么为char保留0xbffff048、0xbffff049、0xbffff04a和0xbffff04b

这个符号还"3\005"意味着什么?

另一方面,如果我的方法如下,则该字符没有填充空间,且具有三个额外的存储字节

void addme()
{
  long a = 5;
  char c = '3';
  char line[9];
  char d = '4';
}

这就是这些变量的内存分配方式(跳过地址的前导部分)

a - f04c 
c - f04b 
d - f04a 
line - f041, f042, f043, f044, f045, f046, f047, f048, f049

也不确定为什么在内存保留中d悬挂了以上内容line我假设是因为它没有被初始化,所以它与已初始化变量一起进入堆栈中的不同区域?

如果

这称为对齐对象与特定整数的倍数对齐(对于,通常为4或8 long)以进行快速访问。通常,您不需要太担心C ++中的位置,因为语言规范通常使编译器可以选择最有效的方式(就您的优化方向而言)来存储对象,通常是这种情况。

每个对象类型都有一个称为“对齐要求”的属性,该属性是一个整数值(类型std::size_t,始终为的幂2),表示可以在其上分配此类型对象的连续地址之间的字节数。可以使用alignof查询类型的对齐要求std::alignment_of指针对齐功能std::align可用于在某个缓冲区中获取适当对齐的指针,std::aligned_storage并可用于获取适当对齐的存储。

每个对象类型都对该类型的每个对象施加其对齐要求;可以使用要求更严格的对齐方式(具有更大的对齐要求)alignas

为了满足所有非静态成员类别的对齐要求,可以在其某些成员之后插入填充

cppreference


关于第二个问题,@ prl给出答案:

因为cchar&cchar *,所以gdb将其打印为字符串。字符串的第一个字符为'3',值为c下一个字符是5的低字节a,gdb以八进制转义符号打印。Wikipedia上C中的转义序列– prl 1024分钟前


当在chars之后声明s时,为什么垫消失char因为在这种情况下,char的对齐方式似乎为1,这意味着不需要填充。另一方面,long的似乎是4,因此必须在其中char放置一个4字节的空间

我假设是因为它没有被初始化,所以它与已初始化变量一起进入堆栈中的不同区域?

并不是的。变量是否已初始化(通常)不会影响其放置,只会影响它具有不确定的值。另一方面,编译器可以按照自己喜欢的方式随意将对象放置在内存中。在实践中,编译器“享受”可在内存和时间上提高效率的实现。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我的局部变量没有被覆盖?

来自分类Dev

为什么要保留局部变量的堆栈空间?

来自分类Dev

为什么必须为存储在堆中的函数的局部变量调用delete?

来自分类Dev

为什么全局变量没有在没有将其重新声明为局部变量的函数内更新?

来自分类Dev

当存储该引用的局部变量设置为null时,为什么静态变量没有设置为null?

来自分类Dev

为什么函数局部变量和参数被压入堆栈?

来自分类Dev

在类构造函数中,为什么“这是必需的”?为什么我不能使用局部变量?

来自分类Dev

为什么我的Go调试器没有加载所有符号,导致调试器中缺少局部变量?

来自分类Java

为什么即使事后没有修改,Java中的局部变量也不被视为“有效的最终变量”?

来自分类Java

为什么在基于堆栈的IL字节码中有局部变量

来自分类Dev

是否有存储在堆栈帧中的局部变量的符号表?

来自分类Dev

为什么分配给堆栈中的局部变量的内存比C ++所需的内存多?

来自分类Dev

requirejs:为什么模块中定义的函数无法访问require()中的局部变量,我该如何实现?

来自分类Dev

为什么constexpr没有唯一的值或存储空间?

来自分类Dev

有没有办法知道使用LLVM中的alloca指令创建的堆栈分配的局部变量的堆栈地址

来自分类Dev

为什么BigQuery有自己的存储空间?

来自分类Dev

为什么在此函数中全局变量与局部变量不同?

来自分类Java

为什么Spring Security将SecurityContext存储在线程局部变量中

来自分类Dev

为什么eclipse会说即使使用了局部变量也没有使用?

来自分类Dev

为什么我不能从python中的异常返回我的局部变量?

来自分类Dev

为什么函数能够返回局部变量?

来自分类Dev

为什么我的局部变量为null?

来自分类Dev

为什么局部变量会自我更新?

来自分类Dev

为什么我得到“赋值前引用的局部变量”?

来自分类Dev

为什么我在堆栈中启动的变量之间存在“差距”?

来自分类Dev

为什么/如何确定函数何时覆盖Julia中的局部变量?

来自分类Dev

为什么不能在ngAfterViewInit函数中访问局部变量?

来自分类Dev

为什么函数无法访问外部声明的对象中的局部变量

来自分类Dev

为什么在函数中的 IF 语句之后分配局部变量的语法无效?

Related 相关文章

  1. 1

    为什么我的局部变量没有被覆盖?

  2. 2

    为什么要保留局部变量的堆栈空间?

  3. 3

    为什么必须为存储在堆中的函数的局部变量调用delete?

  4. 4

    为什么全局变量没有在没有将其重新声明为局部变量的函数内更新?

  5. 5

    当存储该引用的局部变量设置为null时,为什么静态变量没有设置为null?

  6. 6

    为什么函数局部变量和参数被压入堆栈?

  7. 7

    在类构造函数中,为什么“这是必需的”?为什么我不能使用局部变量?

  8. 8

    为什么我的Go调试器没有加载所有符号,导致调试器中缺少局部变量?

  9. 9

    为什么即使事后没有修改,Java中的局部变量也不被视为“有效的最终变量”?

  10. 10

    为什么在基于堆栈的IL字节码中有局部变量

  11. 11

    是否有存储在堆栈帧中的局部变量的符号表?

  12. 12

    为什么分配给堆栈中的局部变量的内存比C ++所需的内存多?

  13. 13

    requirejs:为什么模块中定义的函数无法访问require()中的局部变量,我该如何实现?

  14. 14

    为什么constexpr没有唯一的值或存储空间?

  15. 15

    有没有办法知道使用LLVM中的alloca指令创建的堆栈分配的局部变量的堆栈地址

  16. 16

    为什么BigQuery有自己的存储空间?

  17. 17

    为什么在此函数中全局变量与局部变量不同?

  18. 18

    为什么Spring Security将SecurityContext存储在线程局部变量中

  19. 19

    为什么eclipse会说即使使用了局部变量也没有使用?

  20. 20

    为什么我不能从python中的异常返回我的局部变量?

  21. 21

    为什么函数能够返回局部变量?

  22. 22

    为什么我的局部变量为null?

  23. 23

    为什么局部变量会自我更新?

  24. 24

    为什么我得到“赋值前引用的局部变量”?

  25. 25

    为什么我在堆栈中启动的变量之间存在“差距”?

  26. 26

    为什么/如何确定函数何时覆盖Julia中的局部变量?

  27. 27

    为什么不能在ngAfterViewInit函数中访问局部变量?

  28. 28

    为什么函数无法访问外部声明的对象中的局部变量

  29. 29

    为什么在函数中的 IF 语句之后分配局部变量的语法无效?

热门标签

归档