一个重载operator new的例子

------------恢复内容开始------------

这个代码来自effictive c++ 249页,用来在申请内存的时候在内存的前后两端加入标志,这样在发生访问越界的时候便于检查。

之所以要写这段代码是因为我觉得这段代码里面我觉得比较稀奇的地方。

 1 //重载operator new使得在分配内存的时候   在前后两端加入标志位
 2 class base{
 3 private:
 4     int val;
 5 public:
 6     static const int signature;
 7     typedef unsigned char Byte;
 8     base(int a) :val(a){}
 9     void* operator new(std::size_t size) throw(std::bad_alloc){
10         using namespace std;
11         cout << "int the operator new" << endl;
12         //第0步 确定待分配内存的大小  以字节计
13         int new_size = size + 2 * sizeof(int);
14         //第一步  分配内存
15         void *p = malloc(new_size); //得到新分配内存的指针
16         if (p == NULL) throw bad_alloc();
17         //第二步在起始点和终止点填值
18         *((int *)p) = signature;
19         *(int *)((Byte *)p + size + sizeof(int)) = signature;
20         return (void *)((Byte *)p + sizeof(int));
21     }
22 };
23 const int base::signature = 0xDEAFFFFF;
24
25 int _tmain(int argc, _TCHAR* argv[]){
26     
27     base *p = new base(10);
28     return 0;
29 }

运行结果:

一个重载operator new的例子

以上代码和书上的代码有一点点区别 

1 *(static_cast<int *>(p)) = signature;
2 *(reinterpret_cast<int *>(static_cast<Byte*>(p)+new_size-sizeof(int))) = signature;

这是c++风格的数距类型转换。下面对c++的各种数据类型转换做简要说明。

1 const_cast<T> (exp); //用于去除const属性
2 dynamic_cast<T> (exp); //派生类向基类的转换 或者说 安全向下转型
3 reinterpret_cast<T>(exp); //不改变存储为 改变解释 用于底层转换
4 static_cast<T> (exp); //强制执行隐式类型转换
 1 int _tmain(int argc, _TCHAR* argv[]){
 2     
 3     int a = 10;
 4     int *p = &a;
 5     std::cout << (int)(p) << std::endl;
 6     //std::cout << (static_cast<int>(p)) << std::endl;    // 不存在指针转换为int的隐式转换
 7     std::cout << (reinterpret_cast<int>(p)) << std::endl;
 8 
 9     double dd = 5.14;
10     float ff = 2.14;
11     std::cout << (static_cast<int>(dd)) << std::endl;
12     //std::cout << (reinterpret_cast<int>(ff)) << std::endl;  // 将存储float类型直接转换为int是不被允许的
13 
14     char *pc1 = reinterpret_cast<char *>(p);
15     //char *pc2 = static_cast<char *>(p);   // 不存在 int * 向 char *的隐式转换
16 
17     void *pc3 = NULL;
18     int *pp = NULL;
19     char *pc4 = static_cast<char *> (pc3);
20     //char *pc4 = static_cast<char *> (pp);  //  不存在 int * 向 char *的隐式转换
21 
22     return 0;  
23 }

关于上面的代码是存在问题的,问题在于:

在使用new的时候前面去除4直接存放int这样会导致后面的存储内容可能出现地址没对齐的情况。

所谓地址没对齐是指:存放数据的地址的位置不满住地址大小的整数倍。

如:int 型必须的地址必须是4的整数倍。   double 必须要求地址是8的整数倍。

原文链接: https://www.cnblogs.com/xiongxinxzy/p/13065423.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    一个重载operator new的例子

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/353795

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午8:15
下一篇 2023年3月2日 上午8:15

相关推荐