Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@rednaxelafx
Created October 31, 2013 02:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save rednaxelafx/7243503 to your computer and use it in GitHub Desktop.
Save rednaxelafx/7243503 to your computer and use it in GitHub Desktop.
explore memory layout of g++-4.4.5/libstdc++'s std::string
rednaxelafx@fx-laptop:/tmp
$ gedit xx.cpp
rednaxelafx@fx-laptop:/tmp
$ g++ -g xx.cpp
rednaxelafx@fx-laptop:/tmp
$ g++ -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.4.4-14ubuntu5.1' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5.1)
rednaxelafx@fx-laptop:/tmp
$ gdb ./a.out
GNU gdb (GDB) 7.2-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/a.out...done.
(gdb) b main
Breakpoint 1 at 0x400adf: file xx.cpp, line 6.
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, main () at xx.cpp:6
6 string foo("foo"); // (1)
(gdb) n
7 string goo = foo; // (2)
(gdb) p foo
$14 = {static npos = <optimized out>,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x603028 "foo"}}
(gdb) p/x &foo
$15 = 0x7fffffffd750
(gdb) x/g &foo
0x7fffffffd750: 0x0000000000603028
(gdb) p *(((std::string::_Rep*)foo._M_dataplus._M_p)-1)
$16 = {<std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep_base> = {_M_length = 3, _M_capacity = 3, _M_refcount = 0},
static _S_max_size = <optimized out>, static _S_terminal = <optimized out>,
static _S_empty_rep_storage = {0, 0, 0, 0}}
(gdb) x/4g (((std::string::_Rep*)foo._M_dataplus._M_p)-1)
0x603010: 0x0000000000000003 0x0000000000000003
0x603020: 0x0000000000000000 0x00000000006f6f66
(gdb) n
8 goo[0] = 'g'; // (3)
(gdb) p foo
$17 = {static npos = <optimized out>,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x603028 "foo"}}
(gdb) p/x &foo
$18 = 0x7fffffffd750
(gdb) x/g &foo
0x7fffffffd750: 0x0000000000603028
(gdb) p *(((std::string::_Rep*)foo._M_dataplus._M_p)-1)
$19 = {<std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep_base> = {_M_length = 3, _M_capacity = 3, _M_refcount = 1},
static _S_max_size = <optimized out>, static _S_terminal = <optimized out>,
static _S_empty_rep_storage = {0, 0, 0, 0}}
(gdb) x/4g (((std::string::_Rep*)foo._M_dataplus._M_p)-1)
0x603010: 0x0000000000000003 0x0000000000000003
0x603020: 0x0000000000000001 0x00000000006f6f66
(gdb) p goo
$20 = {static npos = <optimized out>,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x603028 "foo"}}
(gdb) p/x &goo
$21 = 0x7fffffffd740
(gdb) x/g &goo
0x7fffffffd740: 0x0000000000603028
(gdb) n
9 cout << foo << endl;
(gdb) p foo
$22 = {static npos = <optimized out>,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x603028 "foo"}}
(gdb) p/x &foo
$23 = 0x7fffffffd750
(gdb) x/g &foo
0x7fffffffd750: 0x0000000000603028
(gdb) p *(((std::string::_Rep*)foo._M_dataplus._M_p)-1)
$24 = {<std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep_base> = {_M_length = 3, _M_capacity = 3, _M_refcount = 0},
static _S_max_size = <optimized out>, static _S_terminal = <optimized out>,
static _S_empty_rep_storage = {0, 0, 0, 0}}
(gdb) x/4g (((std::string::_Rep*)foo._M_dataplus._M_p)-1)
0x603010: 0x0000000000000003 0x0000000000000003
0x603020: 0x0000000000000000 0x00000000006f6f66
(gdb) p goo
$25 = {static npos = <optimized out>,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x603058 "goo"}}
(gdb) p/x &goo
$26 = 0x7fffffffd740
(gdb) x/g &goo
0x7fffffffd740: 0x0000000000603058
(gdb) p *(((std::string::_Rep*)goo._M_dataplus._M_p)-1)
$27 = {<std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep_base> = {_M_length = 3, _M_capacity = 3, _M_refcount = -1},
static _S_max_size = <optimized out>, static _S_terminal = <optimized out>,
static _S_empty_rep_storage = {0, 0, 0, 0}}
(gdb) x/4g (((std::string::_Rep*)goo._M_dataplus._M_p)-1)
0x603040: 0x0000000000000003 0x0000000000000003
0x603050: 0x00000000ffffffff 0x00000000006f6f67
(gdb) cont
Continuing.
foo
goo
Program exited normally.
(gdb) quit
rednaxelafx@fx-laptop:/tmp
$
#include <string>
#include <iostream>
using namespace std;
int main() {
string foo("foo"); // (1)
string goo = foo; // (2)
goo[0] = 'g'; // (3)
cout << foo << endl;
cout << goo << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment