Reputation: 1457
I did it like this:
static wchar_t* Convert1(tDWORD data)
{
wchar_t result[10];
swprintf(result, sizeof(result) / sizeof(*result), L"%d", data);
wprintf(L"[%ls]\n", result);
return result;
}
And it didn't work, I guess because of stack memory has been cleared after return (Could someone explain to me why?). Then I tried like this:
static wchar_t* Convert2(tDWORD data)
{
wchar_t* result = (wchar_t*)malloc(sizeof(wchar_t) * 10);
swprintf(result, sizeof(result) / sizeof(*result), L"%d", data);
wprintf(L"[%ls]\n", result);
return result;
}
And it works, but I get only first digit of any number, and not the whole number. How to do this the right way ?
Upvotes: 1
Views: 6963
Reputation: 62492
In the first case you're returning a pointer to a buffer on the stack, which will be destroyed when your function returns. In the second case you're allocating memory which the caller will have to be responsible for.
Try this:
static std::wstring Convert1(DWORD data)
{
const size_t bufferSize = 10;
wchar_t result[bufferSize];
swprintf(result, bufferSize, L"%d", data);
return result;
}
or for a more C++ aproach...:
static std::wstring Convert1(DWORD data)
{
std::wostringstream stream;
stream << data;
return stream.c_str();
}
Upvotes: 2
Reputation: 14454
You are thinking of result
as a string of characters, which is a natural enough to think. However, severely speaking, result
is not a string of characters but rather the address of the initial character only. Therefore, sizeof(result)
does not do what you think. Try wcslen()
or wcsnlen()
—though, really, what you might prefer to do is to learn C++-style strings.
Regarding Convert1()
, you are right: result
is a local array, allocated on the stack, deallocated when its function returns.
By the way, your Convert2()
may leak memory, depending on how its caller handles it. You might prefer to have it return a std::shared_ptr
or, better, std::unique_ptr
, instead of a plain pointer for this reason.
Upvotes: 1
Reputation: 66234
Consider using a string stream and a by-val wstring, such as:
#include <iostream>
#include <sstream>
#include <string>
#include <cstdint>
using namespace std;
typedef uint32_t tDWORD;
static std::wstring Convert1(tDWORD data)
{
std::wostringstream os;
os << data;
return os.str();
}
int main(int argc, char *argv[])
{
tDWORD dwTest = 1024;
std::wstring res = Convert1(dwTest);
std::wcout << res << std::endl;
return EXIT_SUCCESS;
}
Output
1024
Sorry I had to fake the typedef. Hope it is close to what you were using. The major benefit of doing this is all the memory management, conversion, etc, is handled for you by the library, having to hand-roll near-nothing on your side.
Upvotes: 3
Reputation: 4511
Try this:
static wchar_t* Convert1(tDWORD data)
{
wchar_t *result = new wchar_t[10];
swprintf(result, 10, L"%d", data);
wprintf(L"[%ls]\n", result);
return result;
}
You tried to return the adress of the local variable (array) - local variables are cleared after returning of their scope. That's why you say that the memory was cleared. Also, allocating memory like this: wchar_t result[10]
is allocating memory on stack. Allocating like this: new wchar_t[10]
is allocating memory on heap.
Also, I replaced sizeof(result) / sizeof(*result)
with just 10
. You cannot measure array capacity in C++, unfortunately :)
You can also use your wchar_t* result = (wchar_t*)malloc(sizeof(wchar_t) * 10);
instead of my wchar_t *result = new wchar_t[10];
- my solution is only a bit clear, but it does the same.
Upvotes: 4