int main(void)
{
std::string foo("foo");
}
My understanding is that the above code uses the default allocator to call new. So even though the std::string foo is allocated on the stack the internal buffer inside of foo is allocated on the heap.
How can I create a string that is allocated entirely on the stack?
The object str (it is the instance of the class std::string ) is allocated in the stack. However, the string data itself MAY BE allocated in the heap. It means the object has an internal pointer to a buffer that contains the actual string.
The c++ solution for strings are quite different from the c-version. The first and most important difference is while the c using the ASCIIZ solution, the std::string and std::wstring are using two iterators (pointers) to store the actual string.
In the case of strings being initialized via string literals (ie: "stack" ), it is allocated in a read-only portion of memory. The string itself should not be modified, as it will be stored in a read-only portion of memory.
We can allocate variable length space dynamically on stack memory by using function _alloca. This function allocates memory from the program stack. It simply takes number of bytes to be allocated and return void* to the allocated space just as malloc call.
I wanted to do just this myself recently and found the following code illuminating:
Chronium's stack_container.h
It defines a new std::allocator
which can provide stack-based allocation for the initial allocation of storage for STL containers. I wound up finding a different way to solve my particular problem, so I didn't actually use the code myself, but perhaps it will be useful to you. Do be sure to read the comments in the code regarding usage and caveats.
To those who have questioned the utility and sanity of doing this, consider:
Some people have commented that a string that uses stack-based allocation will not be a std::string
as if this somehow diminishes its utility. True, you can't use the two interchangeably, so you won't be able to pass your stackstring
to functions expecting a std::string
. But (if you do it right), you will be able to use all the same member functions on your stackstring
that you use now on std::string
, like find_first_of()
, append()
, etc. begin()
and end()
will still work fine, so you'll be able to use many of the STL algorithms. Sure, it won't be std::string
in the strictest sense, but it will still be a "string" in the practical sense, and it will still be quite useful.
The problem is that std::basic_string
has a template parameter for the allocator. But std::string
is not a template and has no parameters.
So, you could in principle use an instantiation of std::basic_string
with an allocator that uses memory on the stack, but it wouldn't be a std::string
. In particular, you wouldn't get runtime polymorphism, and you couldn't pass the resulting objects into functions expecting a std::string
.
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