12

What's wrong with this:

wchar_t * t = new wchar_t;

t = "Tony";

I thought I could use a wchar_t pointer as a string...

Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
  • possible duplicate of [What is wrong with this code?](http://stackoverflow.com/questions/3080137/what-is-wrong-with-this-code) or http://stackoverflow.com/questions/1577765/why-must-a-pointer-to-a-char-array-need-strcpy-to-assign-characters-to-its-array – bk1e Jun 25 '10 at 04:41

6 Answers6

27

Your code has two issues.

First, "Tony" is a pointer to a string of char's. L"Tony" is the appropriate wide string.

Second, you allocate a single wchar_t via new, then immediately lose track of it by reassigning the pointer to Tony. This results in a memory leak.

alk
  • 69,737
  • 10
  • 105
  • 255
Michael
  • 54,279
  • 5
  • 125
  • 144
  • 4
    To expand on Michael's explanation, the correct syntax would be `wchar_t* t = L"Tony";`. This would declare a pointer and initialize it to point to the static (wide) string "Tony". – bta Jun 24 '10 at 17:45
  • 3
    The syntax Should actually be `wchar_t const* t = L"Tony";`. To see why, consider the statement `*(t+1) = L'i';` – MSalters Jun 25 '10 at 09:10
12

A pointer just points to a single value. This is important.

All you've done is allocated room for a single wchar_t, and point at it. Then you try to set the pointer to point at a string (remember, just at the first character), but the string type is incorrect.

What you have is a string of char, it "should" be L"Tony". But all you're doing here is leaking your previous memory allocation because the pointer holds a new value.

Rather you want to allocate enough room to hold the entire string, then copy the string into that allocated memory. This is terrible practice, though; never do anything that makes you need to explicitly free memory.

Just use std::wstring and move on. std::wstring t = L"Tony";. It handles all the details, and you don't need to worry about cleaning anything up.

GManNickG
  • 494,350
  • 52
  • 494
  • 543
7

Since you are a C# developer I will point out a few things c++ does different.

This allocates a new wchar_t and assigns it to t

wchar_t* t = new wchar_t

This is an array of constant char

"Tony" 

To get a constant wchar_t array prefix it with L

L"Tony"

This reasigns t to point to the constant L"Tony" instead of your old wchar_t and causes a memory leak since your wchar_t will never be released.

t = L"Tony"

This creates a string of wide chars (wchar_t) to hold a copy of L"Tony"

std::wstring t = L"Tony"

I think the last line is what you want. If you need access to the wchar_t pointer use t.c_str(). Note that c++ strings are mutable and are copied on each assignment.

The c way to do this would be

const wchar_t* t = L"Tony"

This does not create a copy and only assigns the pointer to point to the const wchar array

josefx
  • 15,506
  • 6
  • 38
  • 63
5

What this does is first assign a pointer to a newly allocated wchar_t into t, and then try to assign a non-wide string into t.

Can you use std::wstring instead? That will handle all your memory management needs for you.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • wstring only exists in MSVC. It's not standard. – Pavel Radzivilovsky Jun 24 '10 at 17:38
  • 7
    @Pavel: That is very wrong. wstring is `typedef`'ed as a `basic_string` and exists on *every* compliant C++ system/toolchain. – rubenvb Jun 24 '10 at 17:41
  • 6
    @Pavel: §21.2/2: "The header `` also defines two specific template classes `string` and `wstring` and their special traits." – GManNickG Jun 24 '10 at 17:43
  • 1
    @Pavel Radzivilovsky wstring is standard (at least the cppreference says it is http://www.cppreference.com/wiki/string/start and all wstring wstringstream,wcin,... classes work with g++) the only thing here could be microsoft not implementing the c++ standard. – josefx Jun 24 '10 at 17:47
  • They did implement a fairly-standard `wstring` back in '98, in their VC6 release. More recent versions have removed some minor non-compliances in their `wstring` implementation. (The most important was that `wchar_t` was a typdef in VC6) – MSalters Jun 25 '10 at 09:14
0

you can, its just that "Tony" is a hardcoded string, and they're ANSI by default in most editors/compilers. If you want to tell the editor you're typing in a Unicode string, then prefix it with L, e.g. t = L"Tony".

You have other problems with your code, your allocation is allocating a single Unicode character (2 bytes), then you're trying to point the original variable to the constant string, thus leaking those 2 bytes.

If you want to create a buffer of Unicode data and place data into it, you want to do:

wchar_t* t = new wchar_t[500];
wcscpy(t, "Tony");
gbjbaanb
  • 51,617
  • 12
  • 104
  • 148
-1

this is completely wrong. There's no need to allocate two bytes, make t to point to them, and then overwrite the pointer t leaking the lost memory forever.

Also, "Tony" has a different type. Use:

wchar_t *t = L"Tony";

IMHO better don't use wchars at all - See https://stackoverflow.com/questions/1049947/should-utf-16-be-considered-harmful

Community
  • 1
  • 1
Pavel Radzivilovsky
  • 18,794
  • 5
  • 57
  • 67
  • 4
    Also a wchar_t isn't necessarily two bytes. In the version of gcc I'm using a wchar_t is 4 bytes, and the standard says it's compiler specific. It can even be a single byte. – Niki Yoshiuchi Jun 24 '10 at 18:59