0
#ifndef UNICODE
#define UNICODE
#endif

#include <iostream>
#include <Windows.h>
#include <queue>

using namespace std;

void addSomeContent(queue<TCHAR*> &s)
{
    static int counter=0;
    TCHAR buffer[30];

    wsprintf(buffer,TEXT("foo%d"),counter);

    s.push(buffer);
    counter++;

    if(counter < 10)
    addSomeContent(s);
}


int main (void)
{
    queue<TCHAR*> strings; 

    addSomeContent(strings);

    while(!strings.empty()) 
    {   
        wcout<<strings.front()<<endl;
        strings.pop();
    }

    system("pause");
    return (0);
}

Output:

foo0

Desired:

foo0
foo1
.
.
.
foo9

Where am I wrong?

0x6B6F77616C74
  • 2,559
  • 7
  • 38
  • 65
  • 2
    Read this: http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – chris Sep 20 '12 at 20:21

3 Answers3

4

The reason is that your buffer is a local variale on stack. Once you leave the function, it will expire.

If you really want to do this way, create it on heap TCHAR *buffer = new TCHAR[30];. And you might need to delete[] it after some point.

However, I think using some built-in types or stl containers instead of manipulating pointers will make your code more readable and manageable.

xvatar
  • 3,229
  • 17
  • 20
1

when you do

s.push(buffer);

you add the pointer to buffer to the queue several times (you would get identical copies of the last string in the best case), but that pointer will is invalid once you reach the end of addSomeContent (giving you a random content if not a segmentation violation). You should add a copy of the string to the queue.

Andre Holzner
  • 18,333
  • 6
  • 54
  • 63
  • 'counter is never increased, expect one string only'. Are you sure? – 0x6B6F77616C74 Sep 20 '12 at 20:31
  • 'You should add a copy of the string to the queue.' - How to implement this? `s.push(*buffer);` doesn't work. – 0x6B6F77616C74 Sep 20 '12 at 20:48
  • 1
    if you really have to use pointers to chars, use [`strdup`](http://pubs.opengroup.org/onlinepubs/009695399/functions/strdup.html) possibly in combination with `auto_ptr` as filipenf suggests or [`shared_ptr`](http://www.boost.org/doc/libs/1_51_0/libs/smart_ptr/shared_ptr.htm#example). But this all is done for you behind the scenes if you use `std::string`. – Andre Holzner Sep 21 '12 at 19:38
  • I agree with Andre, the best option is to use std::string and do the casts to TCHAR whenever you need. – Filipe Felisbino Sep 27 '12 at 12:15
1

The problem is that the TCHAR pointer is in the stack. For you to pass the pointer out of the function you should allocate it in the heap ( with new ).

But why are you using TCHAR instead of std::string?

Filipe Felisbino
  • 2,712
  • 25
  • 26
  • I use TCHAR because it's more "seamless" with Windows API. – 0x6B6F77616C74 Sep 20 '12 at 20:41
  • 1
    So you should use xvatar's suggestion of allocating it using new TCHAR[...]. But you'll have to delete it after the use of the queue, or you will have to wrap it in a std::auto_ptr or something like that... Or... you use std::string :-) – Filipe Felisbino Sep 20 '12 at 20:49
  • `std::auto_ptr` - I've never heard about this utility. Thanks, it would be very useful. – 0x6B6F77616C74 Sep 21 '12 at 00:41