tags:

views:

152

answers:

8

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.

+12  A: 

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.

Carl Norum
+1  A: 

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.

nos
+2  A: 

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).

Martin York
This is true, but not why the OP is getting the values he is. :-)
Omnifarious
A: 

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

Knowles Atchison
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;

Code Clown
A: 

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.

Jay
+2  A: 

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.

Remus Rusanu
Remus Rusanu
A: 

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.

supercat