My code converts C++ strings to CStrings somewhat often, and I am wondering if the original string is allocated on the stack, will the CString be allocated on the stack as well? For instance:
string s = "Hello world"; char* s2 = s.c_str();
Will s2
be allocated on the stack, or in the heap? In other words, will I need to delete s2
?
Conversely, if I have this code:
string s = new string("Hello, mr. heap..."); char* s2 = s.c_str();
Will s2
now be on the heap, as its origin was on the heap?
To clarify, when I ask if s2
is on the heap, I know that the pointer is on the stack. I'm asking if what it points to will be on the heap or the stack.
Will I need to delete s2? No, the character array object returned by c_str is owned by the string object.
The basic_string::c_str() is a builtin function in C++ which returns a pointer to an array that contains a null-terminated sequence of characters representing the current value of the basic_string object.
c_str() converts a C++ string into a C-style string which is essentially a null terminated array of bytes. You use it when you want to pass a C++ string into a function that expects a C-style string (e.g. a lot of the Win32 API, POSIX style functions, etc).
c_str returns a "C string". And C strings are always terminated by a null character. This is C standard.
string s = "Hello world"; char* s2 = s.c_str();
Will s2 be allocated on the stack, or in the heap? In other words... Will I need to delete s2?
No, don't delete s2
!
s2
is on the stack if the above code is inside a function; if the code's at global or namespace scope then s2
will be in some statically-allocated dynamically-initialised data segment. Either way, it is a pointer to a character (which in this case happens to be the first 'H'
character in the ASCIIZ representation of the text content of s
). That text itself is wherever the s
object felt like constructing that representation. Implementations are allowed to do that however they like, but the crucial implementation choice for std::string
is whether it provides a "short-string optimisation" that allows very short strings to be embedded directly in the s
object and whether "Hello world"
is short enough to benefit from that optimisation:
s2
would point to memory inside s
, which will be stack- or statically-allocated as explained for s2
aboves
there would be a pointer to dynamically allocated (free-store / heap) memory wherein the "Hello world\0" content whose address is returned by .c_str()
would appear, and s2
would be a copy of that pointer value.Note that c_str()
is const
, so for your code to compile you need to change to const char* s2 = ...
.
You must notdelete s2
. The data to which s2
points is still owned and managed by the s
object, will be invalidated by any call to non-const
methods of s
or by s
going out of scope.
string s = new string("Hello, mr. heap..."); char* s2 = s.c_str();
Will s2 now be on the heap, as its origin was on the heap?
This code doesn't compile, as s
is not a pointer and a string doesn't have a constructor like string(std::string*)
. You could change it to either:
string* s = new string("Hello, mr. heap...");
...or...
string s = *new string("Hello, mr. heap...");
The latter creates a memory leak and serves no useful purpose, so let's assume the former. Then:
char* s2 = s.c_str();
...needs to become...
char* s2 = s->c_str();
Will s2 now be on the heap, as its origin was on the heap?
Yes. In all the scenarios, specifically if s
itself is on the heap, then:
s
to which c_str()
yields a pointer, it must be on the heap, otherwises
uses a pointer to further memory to store the text, that memory will also be allocated from the heap.But again, even knowing for sure that s2
points to heap-allocated memory, your code does not need to deallocate that memory - it will be done automatically when s
is deleted:
string* s = new string("Hello, mr. heap..."); const char* s2 = s->c_str(); ...use s2 for something... delete s; // "destruct" s and deallocate the heap used for it...
Of course, it's usually better just to use string s("xyz");
unless you need a lifetime beyond the local scope, and a std::unique_ptr<std::string>
or std::shared_ptr<std::string>
otherwise.
c_str()
returns a pointer to an internal buffer in the string
object - you don't ever free()
/delete
it.
It is only valid as long as the string
it points into is in scope. In addition if you call a non-const method of the string
object it is no longer guaranteed to be valid.
http://www.cplusplus.com/reference/string/string/c_str/
(Edited for clarity based on comments below)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With