String Distribution in C ++

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 #0 operator new (size=16) at main.cpp:13 #1 std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) () from /usr/lib/libstdc++.so.6 ... 

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; // Bingo! __p->_M_capacity = __capacity; ... } 

So yes. Programming is cool.

+6
source share
5 answers

When you write

 std::string s = "Hello world"; 

you call the constructor string (const char* s); , the specification of this constructor is Copies the null-terminated character sequence (C-string) pointed by s. Therefore, the designer allocates memory to store the copy.

+5
source

Example 3 .: (note first that you should use std::string *s instead of std::string s , since new returns a pointer).

Using gdb, I set a breakpoint on the std :: cout line and reversed two calls:

The first is new , which you wrote in your code. The second is called from libstdc ++. So.6 (in my case):

 (gdb) backtrace #0 operator new (size=36) at test.cpp:6 #1 0x00007ffff7b78a89 in std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #2 0x00007ffff7b7a495 in char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #3 0x00007ffff7b7a5e3 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #4 0x0000000000400da1 in main () at test.cpp:20 
+3
source
  std::string s = "Hello world"; 

Right side - static memory. The s constructor allocates new memory and copies "Hello world",

+1
source

std :: string is a structure that encapsulates a c-style string.

The first distribution is performed for the string structure of the container.
The second selection is for a copy of a string that is executed in a string construction.

0
source

The string object itself allocates space for the actual characters with new . This is done in the string constructor.

0
source

Source: https://habr.com/ru/post/950078/


All Articles