1
#include <iostream>
#include<list>
using namespace std;

int main()
{
   list<int *>l;
   
   for(int i=0;i<3;i++)
   {
       int a = i;
       
       l.push_back(&a);
   }
   cout<<endl;
    for(auto i=l.begin();i!=l.end();i++)
    {
        cout<<**i<<" ";
        
    }
   return 0;
}

The output I get is 2 2 2. Is it because, the compiler is creating the new variable at the same address everytime??

Edit1: The code is not doing anything. I just wrote this code as an experiment. Also if the code is written like this:

#include <iostream>
#include<list>
using namespace std;

int main()
{
   list<int *>l;
   
   for(int i=0;i<3;i++)
   {
       int *a = new int;
       *a = i;
       l.push_back(a);
   }
   cout<<endl;
    for(auto i=l.begin();i!=l.end();i++)
    {
        cout<<**i<<" ";
        
    }
   return 0;
}

Now i get the output 0 1 2. What is the difference between the two? Isn't also the pointer destroyed after the loop runs once??

  • 2
    Technically yes, but this is Undefined Behavior – IWonderWhatThisAPIDoes Mar 18 '21 at 10:12
  • In your own words, what do you expect `**i` to do? Why do you expect the pointers to be valid at this point? – Karl Knechtel Mar 18 '21 at 10:14
  • I have edited the question, kindly have a look at it, Thanks for your answers. – chaitanya_12789 Mar 18 '21 at 10:19
  • The variable `a` gets destroyed in the second case, but not the `int` that it points to. (The loop body is equivalent to `l.push_back(new int(i));`, where you see more clearly that the lifetime of the new `int` does not depend on any variable's scope.) – molbdnilo Mar 18 '21 at 10:26
  • Does this answer your question? [Why can't I have pointers to objects, which have the same type of pointer as a member variables?](//stackoverflow.com/q/41402407/90527) – outis Mar 26 '22 at 21:02

2 Answers2

2

a is a local variable in the scope of for loop, it'll be destroyed when iteration ends. That means the pointers push_backed into l are dangling. Deference on them like **i later leads to UB, anything is possible.

EDIT

What is the difference between the two? Isn't also the pointer destroyed after the loop runs once??

The pointer a itself gets destroyed, just like a with type int in the 1st code snippet; but the int pointed by a is not destroyed. Which makes dereference later like **i well-formed, it'll print out the value of the ints newed. Note that this code has memory leak because the ints newed are never deleteed.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
0

Your code has undefined behaviour. l.push_back(&a); stores the address of a loop local variable. That variable is destroyed at the end of the loop body. From this point on accessing the memory behind the stored pointer is undefined behaviour. This is especially true for the **i in the second loop.

With undefined behaviour anything can happen. Please compare Undefined, unspecified and implementation-defined behavior.

Werner Henze
  • 16,404
  • 12
  • 44
  • 69