#define private public
#define protected public
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <iostream>
#include <typeinfo>
#include <string>
using namespace std;
//打印内存 BEGIN
inline char hdigit(int n){return "0123456789abcdef"[n&0xf];};
#define LEN_LIMIT 32
#define SUBSTITUTE_CHAR '`'
int isValidPtr(const void*p, int len)
{
if (!p) {
return 0;
}
int ret = 1;
int nullfd = open("/dev/random", O_WRONLY);
if (write(nullfd, p, len) < 0) {
ret = 0;
/* Not OK */
}
close(nullfd);
return ret;
}
static const char* dumpline(char*dest, int linelen, const char*src, const char*srcend)
{
if(src>=srcend) {
return 0;
}
int i;
unsigned long s = (unsigned long)src;
for(i=0; i<8; i++) {
dest[i] = hdigit(s>>(28-i*4));
}
dest[8] = ' ';
dest += 9;
if (isValidPtr(src,linelen/4)) {
for(i=0; i<linelen/4 ; i++) {
if(src+i<srcend) {
dest[i*3] = hdigit(src[i]>>4);
dest[i*3+1] = hdigit(src[i]);
//dest[i*3+2] = ((i+1+(unsigned long)src)&3)?' ':'|';
dest[i*3+2] = ' ';
dest[linelen/4*3+i] = src[i] >= ' ' && src[i] < 0x7f ? src[i] : SUBSTITUTE_CHAR;
}else{
dest[i*3] = dest[i*3+1] = dest[i*3+2] = dest[linelen/4*3+i] = '|';
}
}
} else {
strcpy(dest, "***cannot read***");
i = linelen/4;
}
dest[linelen] = 0;
return src+i;
}
void hexdump( const void *addr, unsigned len)
{
int linelen=80;
static char _buf[128];
char*buf = _buf;//(char*)alloca(linelen+1); // alloca() causes the initialization to fail!!!!
buf[linelen]=0;
const char*start = (char*)addr;
const char*cur = start;
const char*end = start+len;
while(!!(cur = dumpline(buf,linelen,cur,start+len)))
{
//write_log( filename, funcname, lineno, "%s",buf);
printf("0x%s \n",buf);
}
}
//打印内存 END
void print_string_inner_type()
{
//type
//string 里面用到的变量
cout<<"typeid string::traits_type "<<typeid(string::traits_type).name()<<" sizeof:"<<sizeof(string::traits_type)<<endl;
cout<<"typeid string::value_type "<<typeid(string::value_type).name()<<" sizeof:"<<sizeof(string::value_type)<<endl;
cout<<"typeid string::allocator_type "<<typeid(string::allocator_type).name()<<" sizeof:"<<sizeof(string::allocator_type)<<endl;
cout<<"typeid string::size_type "<<typeid(string::size_type).name()<<" sizeof:"<<sizeof(string::size_type)<<endl;
cout<<"typeid string::difference_type "<<typeid(string::difference_type).name()<<" sizeof:"<<sizeof(string::difference_type)<<endl;
cout<<"typeid string::reference "<<typeid(string::reference).name()<<" sizeof:"<<sizeof(string::reference)<<endl;
cout<<"typeid string::const_iterator "<<typeid(string::const_iterator).name()<<" sizeof:"<<sizeof(string::const_iterator)<<endl;
cout<<"typeid string::_Rep "<<typeid(string::_Rep).name()<<" sizeof:"<<sizeof(string::_Rep)<<endl;
//variable
string a("hello");
string b(a);
string::_Rep* st_rep;
st_rep = a._M_rep();
st_rep->_M_length;
st_rep->_M_capacity;
st_rep->_M_refcount;
a._M_dataplus;
a._M_dataplus._M_p;
cout<<"a.c_str():"<<endl;
hexdump(a.c_str(),a.length()+1);
cout<<"_M_rep:"<<endl;
hexdump(a._M_rep(),a.length()+sizeof(string::_Rep));
printf("a._M_dataplus:%p\n",&a._M_dataplus);
printf("a._M_dataplus._M_p:%p\n",a._M_dataplus._M_p);
printf("a._M_rep():%p\n",st_rep);
//b是通过a 拷贝构造生成,b指向的内存地址和a一样,不过 _M_refcount 的值会加一
cout<<"b._M_rep:"<<endl;
hexdump(b._M_rep(),b.length()+sizeof(string::_Rep));
//b重新赋值,不在是a的引用,因此b指向地址和a不一样, a 的_M_refcount 会减一
b="aaa";
cout<<"After operator= a._M_rep:"<<endl;
hexdump(a._M_rep(),a.length()+sizeof(string::_Rep));
cout<<"After operator= b._M_rep:"<<endl;
hexdump(b._M_rep(),b.length()+sizeof(string::_Rep));
//未赋值的string对象,不会调用构造函数,会指向静态内存块的地址 string::_Rep::_S_empty_rep_storage
string e,f;
cout<<"string::_Rep::_S_empty_rep_storage[]:"<<endl;
hexdump(string::_Rep::_S_empty_rep_storage,20);
cout<<"e:"<<endl;
hexdump(e._M_rep(),e.length()+sizeof(string::_Rep));
cout<<"f:"<<endl;
hexdump(f._M_rep(),f.length()+sizeof(string::_Rep));
//static
//string中用到的静态值
cout<<"static string::_Rep::_S_max_size 0x"<<hex<<string::_Rep::_S_max_size<<" sizeof:"<<sizeof(string::_Rep::_S_max_size)<<endl;
cout<<"static string::_Rep::_S_terminal 0x"<<hex<<string::_Rep::_S_terminal<<" sizeof:"<<sizeof(string::_Rep::_S_terminal)<<endl;
}
void test_nagetive_idx()
{
//a[-1]
char c[]={"abcdefgh"};
char* d=&c[2];
cout<<"c:"<<endl;
hexdump(c,sizeof(c));
printf("&d[-1]=%p,d[-1]=%c\n",&d[-1],d[-1]);
}
int main(int argc,char* argv[])
{
print_string_inner_type();
test_nagetive_idx();
return 0;
}
chiyl@centos65 ~/Compile/test » make
g++ -g main.cpp -o test
chiyl@centos65 ~/Compile/test » ./test
typeid string::traits_type St11char_traitsIcE sizeof:1
typeid string::value_type c sizeof:1
typeid string::allocator_type SaIcE sizeof:1
typeid string::size_type m sizeof:8
typeid string::difference_type l sizeof:8
typeid string::reference c sizeof:1
typeid string::const_iterator N9__gnu_cxx17__normal_iteratorIPKcSsEE sizeof:8
typeid string::_Rep NSs4_RepE sizeof:24
a.c_str():
0x0220d028 68 65 6c 6c 6f 00 ||||||||||||||||||||||||||||||||||||||||||hello`||||||||||||||
_M_rep:
0x0220d010 05 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 01 00 00 00 ````````````````````
0x0220d024 00 00 00 00 68 65 6c 6c 6f |||||||||||||||||||||||||||||||||````hello|||||||||||
a._M_dataplus:0x7fff90869ae0
a._M_dataplus._M_p:0x220d028
a._M_rep():0x220d010
b._M_rep:
0x0220d010 05 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 01 00 00 00 ````````````````````
0x0220d024 00 00 00 00 68 65 6c 6c 6f |||||||||||||||||||||||||||||||||````hello|||||||||||
After operator= a._M_rep:
0x0220d010 05 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 ````````````````````
0x0220d024 00 00 00 00 68 65 6c 6c 6f |||||||||||||||||||||||||||||||||````hello|||||||||||
After operator= b._M_rep:
0x0220d040 03 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 ````````````````````
0x0220d054 00 00 00 00 61 61 61 |||||||||||||||||||||||||||||||||||||||````aaa|||||||||||||
string::_Rep::_S_empty_rep_storage[]:
0x00602be0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ````````````````````
e:
0x00602be0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ````````````````````
0x00602bf4 00 00 00 00 ||||||||||||||||||||||||||||||||||||||||||||||||````||||||||||||||||
f:
0x00602be0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ````````````````````
0x00602bf4 00 00 00 00 ||||||||||||||||||||||||||||||||||||||||||||||||````||||||||||||||||
static string::_Rep::_S_max_size 0x3ffffffffffffff9 sizeof:8
static string::_Rep::_S_terminal 0x sizeof:1
c:
0x90869af0 61 62 63 64 65 66 67 68 00 |||||||||||||||||||||||||||||||||abcdefgh`|||||||||||
&d[-1]=0x7fff90869af1,d[-1]=b