为什么堆栈中的函数局部变量之间存在内存空间
Why is there a memory space between my function local variables in the stack?
我在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 05"
(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
当只需要0xbffff04b来存储一个字符时,为什么要为字符c
保留0xbffff448、0xbffff049、0xbfff f04a和0xbfffff f04b?
这个符号"3 05"
是什么意思?
另一方面,如果我的方法如下,则不需要为字符填充三个额外字节的存储
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
之上。我想,因为它没有初始化,所以它会进入堆栈中与初始化变量不同的区域?
这被称为对齐。对象与特定整数的倍数对齐(在long
的情况下通常为4或8),以便快速访问。一般来说,您不需要太担心C++中的位置,因为语言规范通常使编译器能够选择最有效的(就优化方向而言)存储对象的方式,通常就是这种情况。
每个对象类型都有一个名为对齐要求的属性,它是一个整数值(类型为
std::size_t
,总是2
的幂),表示可以分配此类型对象的连续地址之间的字节数。可以使用alignof
或std::alignment_of
查询类型的对齐要求。指针对齐函数std::align
可用于在某个缓冲器内获得适当对齐的指针,而std::aligned_storage
可用于获得适当对齐存储。每个对象类型都将其对齐要求强加给该类型的每个对象;可以使用CCD_ 13来请求更严格的对准(具有更大的对准要求)。
为了满足类的所有非静态成员的对齐要求,可以在其某些成员之后插入填充。
(cppreference)
关于您的第二个问题,@prl给出答案:
因为
c
是char
,&c
是char *
,所以gdb将其打印为字符串。字符串的第一个字符是"3",即c
的值。下一个字符是5,a
的低字节,gdb以八进制转义表示法打印维基百科上C中的转义序列–1024分钟前
当您在char
之后声明char
s时,焊盘为什么会消失?因为在这种情况下,char
的对齐方式看起来是1,这意味着不需要填充。另一方面,long
看起来是4,所以必须有一个4字节的空间,其中放置了char
。
我认为,因为它没有初始化,所以它在堆栈中的区域与初始化的变量不同?
不是。变量是否初始化(通常)不会影响其位置,只会影响其值不确定。另一方面,编译器可以自由地按照自己喜欢的方式将对象放置在内存中。在实践中,编译器"享受";在内存和时间上都能提高效率的实现。
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 为什么C++容器之间存在比较运算符
- 为什么返回前的值和返回后的值之间存在差异?
- 为什么堆栈中的函数局部变量之间存在内存空间
- 相对于一元算术运算符+,C和C++之间存在差异的原因是什么
- 函数返回类型和名称之间存在未知关键字
- 我找不到程序中的歧义,但编译器说 check(int) 和 check(float) 之间存在歧义
- 引用的初始化无效:指针和值之间存在差异
- VS2005调试模式和发布模式之间存在巨大的性能影响
- 为什么在Mac OS X上使用size_t时uint32_t和uint64_t之间存在歧义
- 如何提取两个括号之间存在的字符串
- 来自 vtable 的未定义符号是否意味着接口和实现之间存在错误
- 实时时间和用户时间之间存在巨大差异
- 在程序继续执行的同时,如何使代码的两部分之间存在时间间隔或延迟?C++
- g++输出和Visual Studio输出之间存在差异.浮点变量
- 为什么我的静态方法的返回值与定义的构造函数(在 c++ 中)之间存在类型不匹配?
- 复制构造函数和转发构造函数之间存在冲突
- libc++和libstdc++之间存在差异
- 指针上的interpret_cast在char和unsigned char之间存在缺陷
- 为什么在多重定义的情况下char*和char[]之间存在差异