C++关于地址的问题

来源:百度知道 编辑:UC知道 时间:2024/06/21 15:10:43
class A{
public:
int a;
int b;
};
void main(){
A a;
cout<<&a.a<<endl<<&a.b<<endl;
cout<<"~~~~~~~~~~~"<<endl;
int c;
int d;
cout<<&c<<endl<<&d;
}
为什么类中a,b的地址由小到大,而c,d由大到小

这里关键的一点是因为类是顺序数据结构。

你的程序中类变量a,整型变量c和d都是在栈上分配的。至于把先分配的变量安排在栈的低地址处还是高地址处是由编译器决定的,这和栈的后进先出性质无关。虽然将先分配的变量分配在低地址处符合人们的常规理解,但是相反的策略有更好的性能。所以编译器确实是按先分配的变量先入栈的规则为变量安排空间的。
在本例中(假设Windows),编译器可能会把d安排在(注意,这些地址值不是在编译时决定的硬地址值,而是运行时由运行环境决定的,但它们之间的相对位置是不变的)12ffe0至12ffe3,把c安排在12ffe4至12ffe7,把a安排在12ffe8至12ffef(8字节)。即:
12ffe0 : d 4字节
12ffe4 : c 4字节
12ffe8 : a 8字节
12fff0 : 编译器填充的局部变量

而在类内,编译器是不可以决定把前面的变量安排在低地址还是高地址的,只能是低地址!原因有二:
1)类和结构体、数组等一样,是顺序结构,也就是说要保证按低地址到高地址的顺序分配空间。
例如数组int a[20];
如果按倒序分配空间,那么访问数组时a[0]就成了访问最后一个元素了而a[19]才是第一个元素,注意,在c/c++中,a[b]等价与b[a]等价与*((a) + (b))。
结构体和累也是相同的原因,因为classname.membername和
classpoint->membername中的.和->操作符都是根据membername变量在classname中的偏移来读取数据的,而偏移是正的,是顺序的。

2)类的继承机制要求类变量的成员要按顺序分配空间,因为类变量地址开始处总是类的虚函数表指针(如果有的话),然是是基类的变量,然后是第一层继承类的变量,依此类推。如果按倒序排序,将难以实现多态性。

类的成员是在堆中分配的,变量占用的内存是按照地址从小到大的顺序排列。
局部变量是在栈中分配的,栈的特性就是后进先出,从栈的底部开始使用,所以变量占用的内存是按照地址从大到小排列。