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

顽固

我在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 条评论
登录 后参与评论

相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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