校正:
我搞砸了指针地址的概念和指针指向的地址,因此修改了以下代码。现在它打印出我想要的东西,变量a,c,i,j,k,p在堆栈上,变量b,d在堆上。静态和全局变量在另一个段上。非常感谢你们所有人!
嗯,我知道这两个概念已经深入讨论了......但我仍然对以下代码有疑问:
#include <iostream>
using namespace std;
class A {
};
int N = 10;
void f(int p) {
int j = 1;
float k = 2.0;
A c;
A* d = new A();
static int l = 23;
static int m = 24;
cout << "&c: " << &c << endl;
cout << "&d: " << d << endl;
cout << "&j: " << &j << endl;
cout << "&k: " << &k << endl;
cout << "&l: " << &l << endl;
cout << "&m: " << &m << endl;
cout << "&p: " << &p << endl;
}
int main() {
int i = 0;
A* a;
A* b = new A();
cout << "&a: " << &a << endl;
cout << "&b: " << b << endl;
cout << "&i: " << &i << endl;
cout << "&N: " << &N << endl;
f(10);
return 0;
}
我的结果是:
&a: 0x28ff20
&b: 0x7c2990
&i: 0x28ff1c
&N: 0x443000
&c: 0x28fef3
&d: 0x7c0f00
&j: 0x28feec
&k: 0x28fee8
&l: 0x443004
&m: 0x443008
&p: 0x28ff00
这是非常有趣的,除了全局变量N和函数f中的两个静态变量,它们是l和m,所有其他变量的地址似乎在一起。 (注意:代码和结果已被修改,与此处所说的不相符。)
我搜索了很多关于堆栈和堆的信息。常识是,如果一个对象是由“new”创建的,那么它就在堆上。并且局部变量(例如上面示例中的j和k)在堆栈上。但在我的例子中似乎并非如此。它是否依赖于不同的编译器,或者我的理解是错误的?
非常感谢你们所有人。
答案 0 :(得分:14)
你的理解是错误的。例如,b
是一个指针 - 如果您想要new
创建的对象的地址,则需要打印b
,而不是&b
。 b
是一个局部变量,因此它本身(在&b
处找到)位于堆栈中。
对于您的示例,N
,l
和m
可能位于可执行文件数据部分的某个位置。如您所见,它们具有相似的地址。您打印的每个其他变量都在堆栈中 - 它们的地址同样相似。其中一些是指向从堆分配的对象的指针,但没有一个打印输出会显示。
答案 1 :(得分:3)
您的理解是正确的。
虽然您在示例中始终采用局部变量的地址
示例:打印d
而不是d
的地址。由于d
是局部变量(因此地址类似于c
),但它是指向动态分配的对象(that is on the heap)
的指针变量。
编译器如何实现堆栈和堆栈会有所不同。
在现代操作系统中,堆栈和堆甚至可以共享相同的区域(即,您可以通过在堆中分配块来实现堆栈)。
答案 2 :(得分:2)
如果要打印任何d
点的地址(在这种情况下它指向堆上的对象),请执行
cout << "d: " << d << endl;
这将打印指针的值,指针的值是它指向的对象的地址。
您的代码
cout << "&d: " << &d << endl;
这会打印d
的地址,正如您在main中定义的d
,它将在堆栈中,您打印指针的地址。有指针本身,它指向的对象,它们是2个单独的东西,有单独的地址。
答案 3 :(得分:2)
在您的示例中,唯一不在一起的是l
,m
和N
。它们是两个静态和一个全局,因此它们不会在堆栈中分配。它们不是来自堆,最有可能的是,它们来自模块的.data段。堆中唯一的一个应该是地址b
指向的地址,但是您打印的是b
本身的地址,而不是它指向的地址。
答案 4 :(得分:0)
从纯C ++的角度来看,两种形式之间的区别仅在于如何管理对象的生命周期。
答案 5 :(得分:0)
静态变量位于数据段中。您还混合了指针的地址和它的值。例如a:
a是堆栈上类型A *的局部变量。 &amp; a还给出了一个地址(在堆栈上)。 a的值是类型A的堆对象的地址;
答案 6 :(得分:0)
你不能依赖各种编译器以同样的方式做事。对于几乎每一段代码,你都会写出堆栈和堆之间的区别是没有意义的。别担心。
答案 7 :(得分:0)
有些人可能无法安全地假设堆栈中相对于堆上的内容的相对地址,也就是说,不是所有指针的相对地址都是从同一个数组派生或分配的(通过malloc) ,calloc等)块。我甚至不确定指针是否必须是可排名的。