Thread: Where do they go?

  1. #1
    Bored Programmer
    Join Date
    Jul 2009
    Location
    Tomball, TX
    Posts
    428

    Where do they go?

    Hey thanks for reading. I was wondering if a variable is declared inside a loop what happens to the data after the loop is over. I read that every variable has a memory address and that is what a pointer points to. If you had a variable in a for statement after the loop ends what happens to the memory location?

    Code:
    for(int a = 0; a < 10; a++)
    {
    }
    At what point does a program write over that memory adress, or does it ever?

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    The concept of scope and how it relates to object lifetimes is not restricted to functions. It goes for variables in loops as well. Being able to access them after they're out of scope is lucky. Unless you use static all your i's are gone after the exit condition is met.

  3. #3
    Bored Programmer
    Join Date
    Jul 2009
    Location
    Tomball, TX
    Posts
    428
    I had thought so as well but
    Code:
    #include <iostream.h>
    int *ptx;
    
    class testmore{
         private:
         public:
            void testa();
    };
    
    void testmore::testa()
    {
      for(int x = 0; x < 4; x++)
      {
         ptx = &x;
      }
    }
    
    void test()
    {
      testmore testA;
      testA.testa();
    }
    
    int main(int argc, char* args[])
    {
      test();
      cout<<*ptx;
      cint.get();
      return 0;
    }
    Will output the end result of the loop even when its contained in a class in a function. ??
    Last edited by Lesshardtofind; 09-16-2010 at 03:28 AM.

  4. #4
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Yes, but you cant always trust that. That value may still be on the stack but you should not use it let alone rely on it.

  5. #5
    Registered User
    Join Date
    Mar 2008
    Location
    Coimbra, Portugal
    Posts
    85
    If you really want to know where it might be and why you might be able to access it, you should read about the stack. Basically most local variables are stored there, as well as, in some conventions, function arguments. I find that after mastering C and C++, it is very useful to know what lies below it in the layer.

  6. #6
    Banal internet user
    Join Date
    Aug 2002
    Posts
    1,380
    Quote Originally Posted by Lesshardtofind View Post
    Hey thanks for reading. I was wondering if a variable is declared inside a loop what happens to the data after the loop is over. I read that every variable has a memory address and that is what a pointer points to. If you had a variable in a for statement after the loop ends what happens to the memory location?
    It depends on the computer's architecture but more than likely nothing happens to the actual memory until something else overwrites it. In the case of a call stack your program itself will overwrite previous stack variables the next time a function is called.

  7. #7
    30 Helens Agree neandrake's Avatar
    Join Date
    Jan 2002
    Posts
    640
    the x variable is placed on the stack when the loop is initialized. inside the loop you set a global pointer to point to that location on the stack. when the loop exits, the stack is adjusted so that the variable x is no longer being used (but the value is typically still there, but unreliably there). the next thing to use the stack (like a function call or locals etc) would then write on top of it, as it was marked unused.
    Environment: OS X, GCC / G++
    Codes: Java, C#, C/C++
    AOL IM: neandrake, Email: neandrake (at) gmail (dot) com

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The memory is like a bunch of boxes. Boxes are reserved for specific uses, and variables are placed in the boxes. When the variables go out of scope, the boxes are no longer reserved, but they still exist.

    Normally the box doesn't get "emptied" (cleared to zero) when it becomes unused, because that's just a waste of time. So you can have really fun bugs where you are referencing a box you shouldn't be referencing, and you may even find the value you are expecting to find there, but that box could be re-purposed at any time and cause you serious problems.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  9. #9
    Bored Programmer
    Join Date
    Jul 2009
    Location
    Tomball, TX
    Posts
    428
    Cool thanks for the info I will read up on stacks now. Its a new term for me. I know that obviously this wouldn't be a solid foundation to lay a program on. The only reason I coded the example is I wanted to take the scientific approach to what I was told and prove it true. To my surprise I found this case to allow it to be recalled, but I noticed if the cout were repeated on the next line then the number came back different, but consistently different. I.E. When I first compiled it I used the loop control 10. Then I changed the control to see if it would cout other numbers and it did, but if I call it again then it reverted back to that original 10 and it did that EVERY time. I found that to be strange. I started a new project to see if I compiled it the first time and it was at a different loop if this would carry over as a new default, and it didn't. So strangly 10 is the default value for that memory adress if it isn't curry being used.

    Last note if I changed the
    Code:
    cout<<*ptx<<endl;
    to

    Code:
    cout<<pts<<endl;
    it couts what I'm guessing is that memory positions hex adress which no matter what I change in the program that cout is consistent and true, just not always the same value stored in that adress. Thanks again for the information on the subject. I've been having problems really wrapping my head around pointers and how they are used so I'm constantly playing around with experiments.

    @ brewbuck yea I'm starting to notice that. When I start getting above 5,000 lines of code in a program, I tend to create bugs if I'm not really careful(obviously becuase I'm still new to this) . So I started on a trek of learning why and how bugs are being created so that I could solidify the foundations of my programs allowing ultimately more complex programs for me to write and still trust.
    Last edited by Lesshardtofind; 09-16-2010 at 12:36 PM.

  10. #10
    Registered User
    Join Date
    Mar 2008
    Location
    Coimbra, Portugal
    Posts
    85
    Quote Originally Posted by Lesshardtofind View Post
    Cool thanks for the info I will read up on stacks now. Its a new term for me. I know that obviously this wouldn't be a solid foundation to lay a program on. The only reason I coded the example is I wanted to take the scientific approach to what I was told and prove it true. To my surprise I found this case to allow it to be recalled, but I noticed if the cout were repeated on the next line then the number came back different, but consistently different. I.E. When I first compiled it I used the loop control 10. Then I changed the control to see if it would cout other numbers and it did, but if I call it again then it reverted back to that original 10 and it did that EVERY time. I found that to be strange. I started a new project to see if I compiled it the first time and it was at a different loop if this would carry over as a new default, and it didn't. So strangly 10 is the default value for that memory adress if it isn't curry being used.
    Who knows what the standard implementation that you are using does? It really shouldn't affect you unless you do evil things You can always try and step through it with a debugger.

    Last note if I changed the
    Code:
    cout<<*ptx<<endl;
    to

    Code:
    cout<<pts<<endl;
    it couts what I'm guessing is that memory positions hex adress which no matter what I change in the program that cout is consistent and true, just not always the same value stored in that adress. Thanks again for the information on the subject. I've been having problems really wrapping my head around pointers and how they are used so I'm constantly playing around with experiments.
    Yes, you're right in assuming that's the pointer's address (the compiler infers the datatype). It outputs it as a hex address, but don't forget it is just an address -- a set of bits which identify a memory location -- how you interpret it is up to you.

    @ brewbuck yea I'm starting to notice that. When I start getting above 5,000 lines of code in a program, I tend to create bugs if I'm not really careful(obviously becuase I'm still new to this) . So I started on a trek of learning why and how bugs are being created so that I could solidify the foundations of my programs allowing ultimately more complex programs for me to write and still trust.
    I get what you mean, I found that really exciting as well. If you learn more and more about what really happens, you get a thrill!. For instance, learn about memory, paging, heap and the stack. Then learn about Assembly and try to see if you can recreate simple C/C++ programs in Assembly -- or just look at a disassembly! Once you get all of this in your head, you'll see how amazing it is and how, even being a low-level language, C can be quite a nice deal of abstraction, at least to me.

    I learnt that by writing tests and by reading up some info. I started out writing a simple OS and learnt a great deal. And now I have written my own C library which works to a pretty good extent with all these concepts. Oh, threading is also nice to learn, and the Unixy way of doing some things (fork()ing, execvp()ing) is nice.

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Lesshardtofind View Post
    Code:
    for(int a = 0; a < 10; a++)
    {
    }
    At what point does a program write over that memory adress, or does it ever?
    You've actually picked a particularly complex example there. It depends on what compiler and what compiler settings are chosen. The scope of a for-loop variable used to be greater than the body of the loop, but in modern compilers that aren't set to a compatibility mode, it is just inside the loop.
    Thus on newer compilers, if you had three such loops one after the other, it could use the same memory location for each for loop variable if it wanted to. Of course it might not even use a memory location at all, since it might be happy just holding the value in a register.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    Code:
    #include <iostream.h>
    int *ptx;
    
    class testmore{
         private:
         public:
            void testa();
    };
    
    void testmore::testa()
    {
      for(int x = 0; x < 4; x++)
      {
         ptx = &x;
      }
      if(true)
         int replace_x = 0;
    }
    
    void test()
    {
      testmore testA;
      testA.testa();
    }
    
    int main(int argc, char* args[])
    {
      test();
      cout<<*ptx;
      cint.get();
      return 0;
    }
    Test that. If my theory is right, replace_x should do just what it's name suggests, and use x's former spot on the stack and assign that spot a value of 0.

  13. #13
    30 Helens Agree neandrake's Avatar
    Join Date
    Jan 2002
    Posts
    640
    Quote Originally Posted by User Name: View Post
    Test that. If my theory is right, replace_x should do just what it's name suggests, and use x's former spot on the stack and assign that spot a value of 0.
    It may depend on the compiler, but I actually think it wouldn't replace x, though I won't try until later. I think typically compilers allocate space they need for all locals, so replace_x would not actually have the same address as x. I do not think space is allocated at runtime for x. But again, it's probably a compiler-specific thing, not set in standards.
    Environment: OS X, GCC / G++
    Codes: Java, C#, C/C++
    AOL IM: neandrake, Email: neandrake (at) gmail (dot) com

  14. #14
    30 Helens Agree neandrake's Avatar
    Join Date
    Jan 2002
    Posts
    640
    On OSX/g++ this prints out 4, the unmodified value of x
    Environment: OS X, GCC / G++
    Codes: Java, C#, C/C++
    AOL IM: neandrake, Email: neandrake (at) gmail (dot) com

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by neandrake View Post
    It may depend on the compiler, but I actually think it wouldn't replace x, though I won't try until later. I think typically compilers allocate space they need for all locals, so replace_x would not actually have the same address as x. I do not think space is allocated at runtime for x. But again, it's probably a compiler-specific thing, not set in standards.
    It's complicated -- if all you have are simple variables (not objects), the compiler might certainly place multiple variables at the same address. To do this, it needs to prove that the lifetimes of those variables do not overlap.

    For more complicated objects, the stack space might not actually be reserved until the object is actually constructed. For instance, a function might return early 99.9% of the time, and only 0.1% of the time does it need to construct some large object on the stack. The compiler might choose to delay the allocation of stack space until the moment the variable comes into scope. Or not.

    Generally I would not assume anything about the layout of variables on the stack -- whether they are even on the stack is a good question. Sometimes variables are optimized completely out of existence. A good modern compiler can sometimes optimize entire OBJECTS out of existence.

    It's extremely important not to reference variables which have gone out of scope.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed