Why doesn't wstring::c_str cause a memory leak if not properly deleted
Asked Answered
C

4

5

Code Segment 1:

wchar_t *aString() 
{
     wchar_t *str = new wchar[5];
     wcscpy(str, "asdf\0");
     return str;
}
wchar_t *value1 = aString();

Code Segment 2

wstring wstr = L"a value";
wchar_t *value = wstr.c_str();

If value from code segment 2 is not deleted then an memory leak does not occur. However, if value1 from code segment 1 is not deleted there is a memory leak. The internal code to wstring::c_str looks the same to me.

Cogan answered 6/8, 2010 at 14:55 Comment(0)
R
11

An important rule: you must use delete on anything that was created by new, and you mustn't delete anything else.

wstr.c_str() returns a pointer to a buffer that's managed by the wstring object. It will be deallocated when the string is destroyed, after which the pointer will no longer be valid. Using delete on this is wrong. The pointer will also be invalidated if you modify the string.

aString() returns a pointer to a buffer that was created using new[], so you must delete it when you've finished with it (using delete[], to match new[]). This is error-prone, which is why it is better practice to use resource-managing classes (like string, wstring, containers and smart pointers) rather than passing around raw pointers and hoping they are treated correctly.

Redhot answered 6/8, 2010 at 15:4 Comment(1)
typo: "when the string is destroyed, after which the pointer will no longer be invalid " -- should be no longer be valid or be invalidRemaremain
G
2

Because c_str() returns you a pointer to the internal representation of the wstring. The class keeps control of the data it contains.

Gauleiter answered 6/8, 2010 at 15:3 Comment(0)
G
2

Taken from the basic_string::c_str() documentation from MSDN:

The returned C-style string should not be modified, as this could invalidate the pointer to the string, or deleted, as the string has a limited lifetime and is owned by the class string.

Gorrian answered 6/8, 2010 at 15:5 Comment(1)
Well yea... the return type of c_str is const char*/wchar_t*Cogan
S
1

I'm going to go out on a limb and say that a wstring is not a wchar_t, but instead a class that has an operator to return a wchar_t *, so in the destructor of wstring, it likely frees its own copy of the wchar_t * it returns.

Smokechaser answered 6/8, 2010 at 14:58 Comment(2)
It's not an operator, it's an explicit function call cstr(). This is one of the most heavily used classes in the standard, I'm really quite shocked that the highest voted answer is guessing about it.Remaremain
I have worked for a long time at a company that has their own string classes from before wide adoption of STL (a bit of a 'not written here' mentality), so for years those are what I have used.Smokechaser

© 2022 - 2024 — McMap. All rights reserved.