Thread: can anyone explain this to me? (stacktest.c)

  1. #1
    Registered User meriororen's Avatar
    Join Date
    Dec 2008
    Posts
    22

    can anyone explain this to me? (stacktest.c)

    I am studying about stack and the teacher gave me this example,

    Code:
    //stacktest.c
    
    #include <stdio.h>
    
    void f(int **p){
    	int x = 1;
    	printf("&x=%p\n",&x);
    	*p = &x;
    }
    
    void g(void){
    	int a = 123;
    	printf("&a=%p\n",&a);
    }
    
    int main(void){
    	int *p;
    	f(&p);
    	g();
    	printf("*p=%d\n",*p);
    	return 0;
    }
    and this program gave this output :

    Code:
    &x=0xbffff758
    &a=0xbffff758
    *p=123
    here, the pointer p gave the value of a (=123) variable instead of x (=1), I didnt get the explanation so clearly.

    so, anyone?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    What do you think the numbers starting with bffff actually mean?

    What does the fact that they are both the same mean?

    What if you printed p with %p inside main?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    DESTINY BEN10's Avatar
    Join Date
    Jul 2008
    Location
    in front of my computer
    Posts
    804
    Quote Originally Posted by meriororen View Post
    I am studying about stack and the teacher gave me this example,

    Code:
    &x=0xbffff758
    &a=0xbffff758
    *p=123
    here, the pointer p gave the value of a (=123) variable instead of x (=1), I didnt get the explanation so clearly.

    so, anyone?
    How are you getting this output? &x and &a should be different. Also *p should be an address which is not 123. I compiled the code and got different values, that's why i'm saying it. But I'm also confused regarding whether *p and &x should be same or not. In my opinion they should be same.
    HOPE YOU UNDERSTAND.......

    By associating with wise people you will become wise yourself
    It's fine to celebrate success but it is more important to heed the lessons of failure
    We've got to put a lot of money into changing behavior


    PC specifications- 512MB RAM, Windows XP sp3, 2.79 GHz pentium D.
    IDE- Microsoft Visual Studio 2008 Express Edition

  4. #4
    Registered User meriororen's Avatar
    Join Date
    Dec 2008
    Posts
    22
    What do you think the numbers starting with bffff actually mean?

    What does the fact that they are both the same mean?

    What if you printed p with %p inside main?
    1. It is the address of a and x?
    2. pointer p points to the same address? (why would it points to the same address ?)
    3. I got different address with the a and x variable.

  5. #5
    Registered User meriororen's Avatar
    Join Date
    Dec 2008
    Posts
    22
    How are you getting this output? &x and &a should be different. Also *p should be an address which is not 123. I compiled the code and got different values, that's why i'm saying it. But I'm also confused regarding whether *p and &x should be same or not. In my opinion they should be same.
    That is my question

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by BEN10
    &x and &a should be different.
    They can be different, but they can be the same since x and a do not exist in the same scope.

    Quote Originally Posted by BEN10
    Also *p should be an address which is not 123.
    In the main function, p is a pointer to int so *p is an int, not an address.

    Quote Originally Posted by BEN10
    But I'm also confused regarding whether *p and &x should be same or not. In my opinion they should be same.
    What do you mean?

    Keep in mind that this exercise is supposed to teach meriororen about the stack, but to be pedantic the code has undefined behaviour since p in main points to an object that no longer exists by the time *p is printed.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User meriororen's Avatar
    Join Date
    Dec 2008
    Posts
    22
    so, lets say if I change p in function f to p1
    Code:
    void f(int **p1){
           int x = 1;
           printf("&x=%p\n", &x);
           *p1 = &x;
    }
    then when the program is executed, p1 points to p that points to x, then function f ends which mean the object x is pushed out of stack (?), after that, function g is called, pushing a into the stack (which was the same address used by x before) and since p is still pointing to that address, *p returns 123.

    is it correct?

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Indeed. The stack is "recycled" when a function returns, and the next function will reuse the same space - think of it as a the stack of plates in a restaurant: plates are taken to serve guests, then when they are no longer in use put back on the top of the stack. [Ok, so the plates in a restaurant get cleaned, in C you get served "dirty" plates, which is why you need to initialize any local variables too!].

    And as a consequence, you must NEVER return the address of a local variable to a calling function - because it's not going to remain there when the function is done.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User meriororen's Avatar
    Join Date
    Dec 2008
    Posts
    22
    Ok, thanks, I get it now.

  10. #10
    DESTINY BEN10's Avatar
    Join Date
    Jul 2008
    Location
    in front of my computer
    Posts
    804
    Quote Originally Posted by meriororen View Post
    so, lets say if I change p in function f to p1
    Code:
    void f(int **p1){
           int x = 1;
           printf("&x=%p\n", &x);
           *p1 = &x;
    }
    then when the program is executed, p1 points to p that points to x, then function f ends which mean the object x is pushed out of stack (?), after that, function g is called, pushing a into the stack (which was the same address used by x before) and since p is still pointing to that address, *p returns 123.

    is it correct?
    'p' is a pointer to an int. 'p1' is a pointer to a pointer to an int, which means p1 has the address of p and p has the address of x. Now when we return from function 'f' x gets destroyed. 'a' has nothing to do with p and x. Now the address of 'x' i.e &x and 'p' are the same. The value at p i.e '*p' is the value of x but as x is destroyed it is a garbage value. So *p in main should not print 123(it's just a coincidence in your case I guess), rather any garbage value.
    HOPE YOU UNDERSTAND.......

    By associating with wise people you will become wise yourself
    It's fine to celebrate success but it is more important to heed the lessons of failure
    We've got to put a lot of money into changing behavior


    PC specifications- 512MB RAM, Windows XP sp3, 2.79 GHz pentium D.
    IDE- Microsoft Visual Studio 2008 Express Edition

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by BEN10 View Post
    So *p in main should not print 123(it's just a coincidence in your case I guess), rather any garbage value.
    Well, p points to the address that the variable a used to have in f. Which so happens to be the same as x in function g [in this case, it's obviously not SURE that this will be the case - the compiler may generate some other code with different compiler settings, or using a different compiler may change things].

    Stack content is generally not cleared when the function exits [Microsoft Compilers do have an option where stack space that has been freed is actually cleared after returning from the function, which makes it possible to detect errors where a pointer to free-stack space is being used], so until the space is being used for a different purpose, the value remains. Add a line of "printf("Hi\n") before the call to printf with *p, and it's highly likely [but not certain] that the value will change.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by BEN10
    Now when we return from function 'f' x gets destroyed. 'a' has nothing to do with p and x. Now the address of 'x' i.e &x and 'p' are the same. The value at p i.e '*p' is the value of x but as x is destroyed it is a garbage value.
    Not necessarily "destroyed" per se for a simple plain-ole-data variable, the current stack pointer is just adjusted (the variable is effectively popped off the stack), the value that was there is still there until it gets overwritten by something else (the next function's local stack data for example) which is what makes it dangerous to use. If it was a C++ class object then the destructor would be called which may or may not involve mangling the data in the memory location of the object on the stack.

    [edit]What he said (the guy above me).[/edit]
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    And since the forum this is in is the C, rather than C++, there are no destructors.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    DESTINY BEN10's Avatar
    Join Date
    Jul 2008
    Location
    in front of my computer
    Posts
    804
    Quote Originally Posted by matsp View Post
    Well, p points to the address that the variable a used to have in f. Which so happens to be the same as x in function g [in this case, it's obviously not SURE that this will be the case - the compiler may generate some other code with different compiler settings, or using a different compiler may change things].

    Stack content is generally not cleared when the function exits [Microsoft Compilers do have an option where stack space that has been freed is actually cleared after returning from the function, which makes it possible to detect errors where a pointer to free-stack space is being used], so until the space is being used for a different purpose, the value remains. Add a line of "printf("Hi\n") before the call to printf with *p, and it's highly likely [but not certain] that the value will change.

    --
    Mats
    So, do you mean *p actually should be 123.
    HOPE YOU UNDERSTAND.......

    By associating with wise people you will become wise yourself
    It's fine to celebrate success but it is more important to heed the lessons of failure
    We've got to put a lot of money into changing behavior


    PC specifications- 512MB RAM, Windows XP sp3, 2.79 GHz pentium D.
    IDE- Microsoft Visual Studio 2008 Express Edition

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by BEN10
    So, do you mean *p actually should be 123.
    No, but that it is not unreasonable to believe meriororen's observation that the output when *p was printed in the main function is 123.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 08-23-2008, 01:16 PM
  2. Please Explain me few terms that i have listed in here.
    By chottachatri in forum C++ Programming
    Replies: 3
    Last Post: 02-26-2008, 08:20 AM
  3. Can someone explain to me what this code means
    By Shadow12345 in forum C++ Programming
    Replies: 3
    Last Post: 12-22-2002, 12:36 PM
  4. Replies: 4
    Last Post: 11-19-2002, 09:18 PM
  5. Can someone explain "extern" to me?
    By valar_king in forum C++ Programming
    Replies: 3
    Last Post: 09-16-2001, 12:22 AM