Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3231703
  • 博文数量: 346
  • 博客积分: 10189
  • 博客等级: 上将
  • 技术积分: 3125
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-05 19:46
文章分类

全部博文(346)

文章存档

2013年(35)

2011年(35)

2010年(76)

2009年(48)

2008年(152)

分类: C/C++

2008-09-02 09:13:33

你私藏了不少好东西(private member),除了friend,不拿出来给别人共享。但是我现在已经知道你有这个东西,而且知道它在你家(class或者struct)的什么位置。 我就派了个窃贼(pointer),通过一条秘道(memory access)把这些东西占为己有。
       简单一点,如果你只是一个收藏家(只有成员变量和公共构造函数),而且你家的地图是这样子的(一看就知道是小家子):
       struct home{
           home(){
               TV = 111;
               CD = 222;
            }
       private :
           int TV, CD;
       };   
       先侦察一下地形:
       cout << sizeof(home) << endl;
       结果是8,就是两个int的大小,因为静态函数是不占类空间的。先摸到你家门口吧,获取一个类指针。
       home *h = new home();
       好,我找来一个窃贼:
       typedef unsigned char byte_t;
     byte_t *ptr = 0;
       其实在这个例子中可以用int类型的指针,但用字节类型的更具有通用性(c++是没有字节类型的,只有自己定义);
       ptr = (byte_t*)h;
       现在已经成功潜入!
       一个类的内存分布是按照成员列表的顺序安排的。
       现在我不想要电视机(h->TV),我只想要Ayaka签名cd(h->CD);
       ptr += 4;//跳过h->TV的内存空间。
       现在已经获得了h->CD的内存初始位置,再进行一次强制转换:
       int *val = 0;
       val = (int*)ptr;
       cout << val << endl;
       打印出222,窃取成功!
       如果类经过了继承,要注意,子类的内存分布是这样的:先排列父类的成员,再排列自己的成员,多重继承以此类推。
       如果类中或者父类中有虚函数,那么要注意类里面有一个虚指针的开销,一般都是在类的头部,比如说:
        struct A{
            int v1;
            A(){
            v1 = 444;
            }
            virtual void pt(){
                v1 = 10;
                cout << v1 << endl;
            }
        };
        struct B : public A{
          private :
                string str;
                int v2, v3;
          public :
              B(){
                    v1 = 333;
                    str = "hello";
                    v2 = 100;
                    v3 = 200;
                }
        };
       sizeof(A)是8,sizeof(B)是20,sizeof(string)是4。
       这时候:
       B *b = new B();
       byte_t *ptr = 0;
       ptr = (byte_t*)b;
       ptr += 4;//略过虚指针
       此时指向的是父类的成员v1,提醒一下,构造的顺序是从父到子,和析构相反。所以这个case里面v1的值是333而不是444。
       ptr += 4;
       此时指向的是子类的string类型的str。
       同样可以把数据窃取出来。
阅读(1272) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~