tags:

views:

103

answers:

2

Let's say I have a loop like this:

vector<shared_ptr<someStruct>> vec;
int i = 0;
while (condition)
{
     i++
     shared_ptr<someStruct> sps(new someStruct());
     WCHAR wchr[20];
     memset(wchr, i, 20); 
     sps->pwsz = wchr;
     vec.push_back(sps);
}

At the end of this loop, I see that for each sps element of the vector, sps->pwsz is the same. Is this because I'm passing a pointer to memory allocated in a loop, which is destructed after each iteration, and then refilling that same memory on the next iteration?

+5  A: 

I don't think this code does what you expect it to. You probably want wchr created on the heap or as a member of someStruct.

wchr is allocated on the stack and gets freed on each iteration. The stack location will be the same on each iteration (probably the same).

Each of your smart pointers contains a pointer to that invalid memory address.

After your while loop all of your smart pointers point to that same invalid already freed address. The address was re-used and freed on each iteration.

Brian R. Bondy
+1 but just a note: "The stack location will be the same on each iteration." Probably, maybe not. Even more probably for a debug build. But it certainly shouldn't matter.
John Dibling
@John: Yes I wasn't sure if it would be the same guaranteed or not but I guess not. I added a note on that.
Brian R. Bondy
Actually, there is a high chance it will be. Compilers commonly reserve the memory for each of the variables used within a function when entering this function (which means that they reserve once, upon entry, and the stack pointer does not move during the function execution, unless it calls another function).
Matthieu M.
+3  A: 

sps->pwsz is a pointer to a char buffer. You give each new sps instance a pointer to the same memory location.

Even worse, that memory location is de-allocated after the loop ends, and will likely be re-used by other code quickly. It is invalid outside the while loop.

To fix this,

  WCHAR * wchr = new WCHAR [20];
Henk Holterman