C++ 中栈和堆的地址

发布于 2024-09-15 16:27:51 字数 1584 浏览 6 评论 0原文

更正:

我搞乱了指针地址和指针指向的地址的概念,所以修改了下面的代码。现在它打印出我想要的东西,变量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)位于堆栈中。但在我的例子中似乎并非如此。是依赖于不同的编译器,还是我的理解有误?

非常感谢大家。

Correction:

I messed up with the concept of pointer address and the address the pointer points to, so the following code has been modified. And now it prints out what I want, variable a, c, i, j, k, p are on the stack, and variable b,d are on the heap. Static and global variables are on another segment. Thanks a lot for all of you!


Well, I know that these two concepts are deeply discussed...but I still have questions for the following code:

#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;
}

My result is:

&a: 0x28ff20
&b: 0x7c2990
&i: 0x28ff1c
&N: 0x443000
&c: 0x28fef3
&d: 0x7c0f00
&j: 0x28feec
&k: 0x28fee8
&l: 0x443004
&m: 0x443008
&p: 0x28ff00

This is pretty interesting, coz except the global variable N, and two static variables in function f, which are l and m, the addresses of all the other variables seem to be together. (Note: The code and the results have been modified and not corresponding to what is said here.)

I've searched a lot about stack and heap. The common sense is that, if an object is created by "new", then it is on the heap. And local variables (such as j and k in the above sample) are on stack. But it seems not to be the case in my example. Does it depend on different compilers, or my understanding is wrong?

Thanks a lot for all of you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

趴在窗边数星星i 2024-09-22 16:27:51

你的理解是错误的。例如,b是一个指针 - 如果你想要new创建的对象的地址,你需要打印出b,而不是<代码>&b。 b 是一个局部变量,因此它本身(在 &b 中找到)位于堆栈上。

对于您的示例,Nlm 可能位于可执行文件数据部分的某个位置。如您所见,它们具有相似的地址。您打印出的每个其他变量都在堆栈上 - 它们的地址同样彼此相似。其中一些是指向从堆分配的对象的指针,但您的打印输出都不会显示这一点。

Your understanding is wrong. For example, b is a pointer - if you want the address of the object created by new, you need to print out b, not &b. b is a local variable, so it itself (found at &b) is on the stack.

For your example, N, l, and m are presumably somewhere in your executable's data section. As you can see, they have similar addresses. Every other variable you are printing out is on the stack - their addresses are likewise similar to one another. Some of them are pointers pointing to objects allocated from the heap, but none of your printouts would show that.

你的笑 2024-09-22 16:27:51

你的理解是正确的。

  • 局部变量在堆栈上分配。
  • 动态分配的对象在堆上分配。

尽管您在示例中一致地获取局部变量的地址。
示例:打印 d 而不是 d 的地址。由于d是一个局部变量(所以地址类似于c),但它是一个指针变量,指向动态分配的对象(即在堆)

编译器实现堆栈和堆的方式会有所不同。

在现代操作系统中,堆栈和堆甚至可以共享相同的区域(即您可以通过在堆中分配块来实现堆栈)。

Your understanding is correct.

  • local variables are allocated on the stack.
  • dynamically allocated objects are allocated on the heap.

Though you are taking the address of the local variable consistently in your example.
Example: print out d not the address of d. As d is a local variable (so the address is similar to c) but it is a pointer variable that points at a dynamically allocated object (that is on the heap).

How the compiler implements the stack and heap though will vary.

In modern OS the stack and heap may even share the same area (ie you can implement the stack by allocating chunks in the heap).

冧九 2024-09-22 16:27:51

如果你想打印 d 所指向的地址(在本例中它指向堆上的一个对象),那么

  cout << "d: " << d << endl;

会打印指针的值,而指针的值是它指向的对象的地址。

您的代码

   cout << "&d: " << &d << endl;

打印了 d 的地址,正如您在 main 中定义的 d 一样,它将位于堆栈上,您将打印指针的地址。有指针本身和它指向的对象,它们是两个单独的东西,具有单独的地址。

If you want to print the address of whatever d points to (in this case it points to an object on the heap), do

  cout << "d: " << d << endl;

That will print the value of the pointer, and the value of a pointer is the address of the object it points to.

Your code had

   cout << "&d: " << &d << endl;

This prints the address of d , as you defined d inside main, it'll be on the stack, you're printing the address of your pointer. There's the pointer itself, and the object it points to, they're 2 seperate things, with seperate addresses.

妄司 2024-09-22 16:27:51

在您的示例中,唯一不“在一起”的是 lmN。它们是两个静态变量和一个全局变量,因此它们肯定不会在堆栈上分配。它们也不是来自堆,很可能它们来自模块的 .data 段。堆中唯一的一个应该是 b 指向的地址,但您打印的是 b 本身的地址,而不是它指向的地址。

The only ones that are not 'together' in your example are l, m and N. They are two statics and one global, therefore they are not allocated on the stack for sure. They aren't from a heap neither, most likely, they are from a .data segment of your module. The only one from a heap should be the address b points to, but you're printing the address of b itself, not what it points to.

你的笑 2024-09-22 16:27:51

从纯 C++ 的角度来看,这两种形式之间的区别仅与对象生命周期的管理方式有关。

从这里开始,很好读

The distinction between the two forms, from a pure C++ perspective, is only to do with how lifetime of objects are managed.

From here, good read

梦归所梦 2024-09-22 16:27:51

静态变量位于数据段中。您还可以混合指针的地址和它的值。例如a:

a是栈上A*类型的局部变量。 &a 还给出了 a 实际驻留的地址(在堆栈上)。 a的值是A类型的堆对象的地址;

Static variables are in the data segment. Also you mix the address of a pointer and it value. For example a:

a is a local variable of type A* on the stack. &a also gives the address where a actaully resieds (on the stack). The value of a is an address of a heap object of type A;

⒈起吃苦の倖褔 2024-09-22 16:27:51

您不能依赖不同的编译器以相同的方式做事。对于您将编写的几乎所有代码,堆栈和堆之间的区别是没有意义的。别担心。

You can't depend on various compilers doing things the same way. For almost every bit of code you will write the distinction between stack and heap are meaningless. Don't worry about it.

感情废物 2024-09-22 16:27:51

人们可能无法安全地假设任何有关堆栈中的内容相对于堆上的内容的相对地址的信息,也不能安全地假设任何并非全部源自同一数组或分配的指针的相对地址(通过 malloc、calloc、等)块。我什至不确定指针是否需要可排名。

One may not safely assume anything about the relative addresses of things in the stack relative to those on the heap nor, for that matter, the relative addresses of any pointers that are not all derived from the same array or allocated (via malloc, calloc, etc.) block. I'm not even sure pointers are required to be rankable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文