I played with new and remote overload operations when I noticed something strange.
I have:
void* operator new(size_t size) { std::cout << "Allocating memory..." << std::endl; void* p = malloc(size); if (NULL == p) { throw std::bad_alloc(); } return p; }
When I do this:
int main() { int* x = new int(1); std::cout << *x << std::endl; delete x; return EXIT_SUCCESS; }
Everything works as expected, and I get:
Allocating memory... 1
But when I do this:
int main() { std::string* s = new std::string("Hello world"); std::cout << *s << std::endl; delete s; return EXIT_SUCCESS; }
I get:
Allocating memory... Allocating memory... Hello world
In fact, when I do:
int main() { std::string s = "Hello world"; return EXIT_SUCCESS; }
I still get Allocating memory... !
Finally, I:
int main() { std::string s = "Hello world"; std::cout << &s << std::endl; while (true); }
To get something like:
$ ./test & [1] 8979 Allocating memory... 0xbfc39a68 $ cat /proc/8979/maps | grep stack bfc27000-bfc3c000 ... [stack]
So, now I'm sure the s variable is allocated on the stack ... but then what causes the new operator? My best guess was that this has something to do with memory allocation for the actual literal, "Hello world" ... but it should be static memory, and new should be all about dynamic memory.
What's happening?
Update
After reading the comments and debugging the example, I would like to conclude that, indeed, after calling the row constructor, it allocates memory on the heap for its internal implementation. This can be seen by following the call to new :
(gdb) b 13 // that the std::cout << "Allocating memory..." << std::endl; line (gdb) r ... Breakpoing 1, operator new (size=16) at test.cpp:13 ... (gdb) backtrace
And after reading std :: string (well, basic_string.tcc ) the source code:
template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::_Rep* basic_string<_CharT, _Traits, _Alloc>::_Rep:: _S_create(size_type __capacity, size_type __old_capacity, const _Alloc& __alloc) { ... void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); _Rep *__p = new (__place) _Rep;
So yes. Programming is cool.
source share