Note that there are some explanatory texts on larger screens.

plurals
  1. POString Allocation In C++
    primarykey
    data
    text
    <p>I was playing with the new and delete operators overloading when I noticed something strange.</p> <ol> <li><p>I have:</p> <pre><code>void* operator new(size_t size) { std::cout &lt;&lt; "Allocating memory..." &lt;&lt; std::endl; void* p = malloc(size); if (NULL == p) { throw std::bad_alloc(); } return p; } </code></pre></li> <li><p>When I do:</p> <pre><code>int main() { int* x = new int(1); std::cout &lt;&lt; *x &lt;&lt; std::endl; delete x; return EXIT_SUCCESS; } </code></pre> <p>Everything works as expected and I get:</p> <pre><code>Allocating memory... 1 </code></pre></li> <li><p>But when I do:</p> <pre><code>int main() { std::string* s = new std::string("Hello world"); std::cout &lt;&lt; *s &lt;&lt; std::endl; delete s; return EXIT_SUCCESS; } </code></pre> <p>I get:</p> <pre><code>Allocating memory... Allocating memory... Hello world </code></pre></li> <li><p>In fact, when I do:</p> <pre><code>int main() { std::string s = "Hello world"; return EXIT_SUCCESS; } </code></pre> <p>I still get <code>Allocating memory...</code>!</p></li> <li><p>Finally, I do:</p> <pre><code>int main() { std::string s = "Hello world"; std::cout &lt;&lt; &amp;s &lt;&lt; std::endl; while (true); } </code></pre> <p>To get something like:</p> <pre><code>$ ./test &amp; [1] 8979 Allocating memory... 0xbfc39a68 $ cat /proc/8979/maps | grep stack bfc27000-bfc3c000 ... [stack] </code></pre> <p>So now I'm sure the <code>s</code> variable is allocated on the stack... but then, what's calling the <code>new</code> operator? My best guess would be it has something to do with the memory allocation for the actual literal, <code>"Hello world"</code>... but it's supposed to be static memory, and <code>new</code> is all about dynamic memory.</p></li> </ol> <p>What's going on?</p> <h1>Update</h1> <p>After reading the comments and debugging the example myself I wanted to conclude that indeed, once the string constructor is called, it allocates memory on the heap for its internal implementation. This can be seen by tracing the <code>new</code> call:</p> <pre><code>(gdb) b 13 // that's the std::cout &lt;&lt; "Allocating memory..." &lt;&lt; std::endl; line (gdb) r ... Breakpoing 1, operator new (size=16) at test.cpp:13 ... (gdb) backtrace #0 operator new (size=16) at main.cpp:13 #1 std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator&lt;char&gt; const&amp;) () from /usr/lib/libstdc++.so.6 ... </code></pre> <p>And reading the std::string (well, <a href="http://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a00771_source.html" rel="nofollow">basic_string.tcc</a>) source code:</p> <pre><code>template&lt;typename _CharT, typename _Traits, typename _Alloc&gt; typename basic_string&lt;_CharT, _Traits, _Alloc&gt;::_Rep* basic_string&lt;_CharT, _Traits, _Alloc&gt;::_Rep:: _S_create(size_type __capacity, size_type __old_capacity, const _Alloc&amp; __alloc) { ... void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); _Rep *__p = new (__place) _Rep; // Bingo! __p-&gt;_M_capacity = __capacity; ... } </code></pre> <p>So yeah. Programming's cool.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload