My code converts C++ strings to C strings somewhat often, and I am wondering if the original string is allocated on the stack. Will the C string 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.
No, don’t
delete s2!s2is on the stack if the above code is inside a function; if the code’s at global or namespace scope thens2will 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 null-terminated string_ representation of the text content ofs). That text itself is wherever thesobject felt like constructing that representation. Implementations are allowed to do that however they like, but the crucial implementation choice forstd::stringis whether it provides a "short-string optimisation" that allows very short strings to be embedded directly in thesobject and whether"Hello world"is short enough to benefit from that optimisation:s2would point to memory insides, which will be stack- or statically-allocated as explained fors2abovesthere 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, ands2would be a copy of that pointer value.Note that
c_str()isconst, so for your code to compile you need to change toconst char* s2 = ....You must not
delete s2. The data to whichs2points is still owned and managed by thesobject, will be invalidated by any call to non-constmethods ofsor bysgoing out of scope.This code doesn’t compile, as
sis not a pointer and a string doesn’t have a constructor likestring(std::string*). You could change it to either:…or…
The latter creates a memory leak and serves no useful purpose, so let’s assume the former. Then:
…needs to become…
Yes. In all the scenarios, specifically if
sitself is on the heap, then:sto whichc_str()yields a pointer, it must be on the heap, otherwisesuses 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
s2points to heap-allocated memory, your code does not need to deallocate that memory – it will be done automatically whensis deleted:Of course, it’s usually better just to use
string s("xyz");unless you need a lifetime beyond the local scope, and astd::unique_ptr<std::string>orstd::shared_ptr<std::string>otherwise.