3

Going through this question, one answer said the object created are destroyed outside their scope, To get this concept clearly I wrote the following code:

#include <iostream>

using namespace std;

struct Node{
    int val;
    Node *next;
    Node(int x) : val(x) , next(NULL){}
};

int main(){
    for(int i=0;i<10;i++){
        int someval = rand()%100;
        Node somenode = Node(someval);
        printf("Address for object %d is %p \n",i+1, &somenode);
    }
}

I got the following output:

Address for object 1 is 0x7ffc32ff26b0 
Address for object 2 is 0x7ffc32ff26b0 
Address for object 3 is 0x7ffc32ff26b0 
Address for object 4 is 0x7ffc32ff26b0 
Address for object 5 is 0x7ffc32ff26b0 
Address for object 6 is 0x7ffc32ff26b0 
Address for object 7 is 0x7ffc32ff26b0 
Address for object 8 is 0x7ffc32ff26b0 
Address for object 9 is 0x7ffc32ff26b0 
Address for object 10 is 0x7ffc32ff26b0 

I understand that each object is destroyed every time the loop iterates and a new object is created; but why do all of them have the same address. This problem occurred to me when I was creating a linked list and I did not use the new operator to create the object instead just used the same code, and the list always pointed to the same node and I ran into an infinite loop. Why is the same address allocated to each object?

Disillusioned
  • 13,820
  • 3
  • 39
  • 75
hulk_baba
  • 87
  • 9
  • It's possible because none of them existed at the same time so they could all have the same address. As for *why* I'm sure there's a more complex answer. – m0meni Jun 05 '17 at 00:03
  • 4
    Why not? Why should the compiler not reuse the memory? – Baum mit Augen Jun 05 '17 at 00:04
  • It's simplest for the compiler. Why not give them the same address? – aschepler Jun 05 '17 at 00:04
  • 3
    "but why all of them have the same address." - why would they not? The compiler is just resusing memory sensibly. –  Jun 05 '17 at 00:04
  • @AR7 so it's just a coincidence or it happens all the time – hulk_baba Jun 05 '17 at 00:04
  • 1
    @user It;s not guaranteed to happen, but for any sensible compiler it will. –  Jun 05 '17 at 00:05
  • @user8111969 it probably happens *most* of the time. Like other commenters have mentioned, why not reuse the same memory? – m0meni Jun 05 '17 at 00:05
  • Yes, you will usually see that behavior when a local variable is declared inside a `for` or `while` loop. Of course, you can't count on it. – aschepler Jun 05 '17 at 00:07
  • 2
    This is very compiler implementation dependent but it looks like simple reuse of the stack. Your objects are created on the stack, not the heap so the stack just goes up and down over the same addresses – AdrianRK Jun 05 '17 at 00:17
  • @aschepler, Thank you. – hulk_baba Jun 05 '17 at 00:18
  • 1
    Re, "I have a follow-up question." You should ask it as a new _Question_ on StackExchange. – Solomon Slow Jun 05 '17 at 03:42
  • @jameslarge I think asking a new question will not be that useful, I took the suggestion from this https://meta.stackexchange.com/questions/10243/asking-a-follow-up-question. I am new to the community and don't know if asking a new question is appropriate in this case. – hulk_baba Jun 05 '17 at 03:54
  • After I read the answers to this question, I have a follow-up question, is there any other way to create multiple objects(I want those objects outside the loop as well) in that loop without using the "new" operator(just by using stack memory)? – hulk_baba Jun 05 '17 at 03:55
  • 1
    StackOverflow is not just a chatroom where you can ask for help and get answers. It also is meant to be a place where you can see the questions that _other_ people asked and the answers that they got. Having only one question per "question" makes it easier for people to search. – Solomon Slow Jun 05 '17 at 04:12
  • @jameslarge, alright, sorry about that, I will ask a new question then. – hulk_baba Jun 05 '17 at 04:20

2 Answers2

7

You keep creating the object on the top of the stack, and then removing it (the object goes out of scope at the end of each loop iteration, and is deconstructed before the next iteration). Thus, the address of the top of the stack is the same everytime you allocate space for the object.

If you remove the loop and allocate multiple Nodes in a row, you'll see different addresses for each as the stack grows.

dlasalle
  • 1,467
  • 3
  • 17
  • 24
  • That is not guaranteed to happen, a possible implementation could perfectly well keep adding the structure to the stack and delete all of them after the final execution of the for loop. – Makogan Jun 05 '17 at 00:20
  • Thank you. According to you explanation, I understand always the address allocated will be same. Can the objects have different addresses? – hulk_baba Jun 05 '17 at 00:24
  • 1
    @Makogan Not likely for stack allocation because stack space is quite limited. Such a strategy would lead to many, um, _stack overflow_ errors in all but the 'shortest' loops. It's also worth noting that for any variable scoped within a loop: a trivial optimisation (regardless of where the compiler decides to store the object), would be to not even re-allocate the object. I.e. simply allocate once before loop, and re-initialise the object for reuse on each iteration. – Disillusioned Jun 05 '17 at 00:35
  • @CraigYoung I am not saying that any sensible compiler WOULD do it, but the C language does not guarantee the behaviour so you should not rely on it. – Makogan Jun 05 '17 at 01:18
  • 1
    @Makogan I'm not contradicting your point that the memory location of the object is not guaranteed. I'm pointing out that your suggestion of "_implementation could perfectly well keep adding the structure to the stack and delete all of them after the final execution_" would be very bad, and that any such implementation would be extremely unlikely to gain much traction due to the severe shortcomings I mentioned in my previous comment. _Your point that the location is not guaranteed is perfectly correct. But the absurdity of your alt implementation weakens the credibility of that fact._ – Disillusioned Jun 05 '17 at 02:03
  • @CraigYoung It was simply an exaggerated and oversimplified example of how you could have the same code being compiled differently by different compilers. It's exaggerated and simplistic on purpose to put the point across. – Makogan Jun 05 '17 at 02:06
  • 1
    @Makogan That technique is referred to as a "straw-man argument"; it is generally considered a weak form of argument. So ironically what you did with the stated purpose "to put the point across" is likely to have the ***exact opposite effect*** on people who notice the straw-man nature of your comment. Fortunately, your [answer](https://stackoverflow.com/a/44360119/224704) handles this much better by making the same point without degenerating into absurdity. That said, this thread is getting way Off Topic.... ;) – Disillusioned Jun 05 '17 at 02:21
  • After I read the answers to this question, I have a follow-up question, is there any other way to create multiple objects(I want those objects outside the loop as well) in that loop without using the "new" operator(just by using stack memory)? – hulk_baba Jun 05 '17 at 03:55
5

This has to do with local variables and scope. Since the variable somenode is declared inside of the {} brackets of the for loop, it's scope is local to that for loop. That is to say, it exists during a single iteration of the for loop and then it goes out of scope before the beginning of the next iteration.

Compilers as a general try to be efficient. After the first iteration of the for loop the address 0x7ffc32ff26b0 points to a location in memory that is big enough to store a Node structure. The compiler also knows that this memory is unused (it went out of scope) so it figures it can just re-use the same memory location. In other words, although the structures occupy the same RAM memory, they are all independent and unrelated to each other.

This behaviour is not guaranteed and you should not rely on it, it's simply an attempt from the compiler to keep the final assembled code as simple and efficient as possible.

Makogan
  • 5,325
  • 3
  • 18
  • 70
  • Thank you, I think I understood it. – hulk_baba Jun 05 '17 at 00:22
  • After I read the answers to this question, I have a follow-up question, is there any other way to create multiple objects(I want those objects outside the loop as well) in that loop without using the "new" operator(just by using stack memory)? – hulk_baba Jun 05 '17 at 03:55
  • you could malloc, bu that uses heap memory I think – Makogan Jun 05 '17 at 05:02