nothrow、reinterpret_cast、位对齐、

nothrow是在C++标准头文件<new>中定义的一个nothrow_t类的对象。nothrow_t类是这样定义的: 
  
  struct   nothrow_t   {   }; 
  
  可见它只是一个什么都不做的空类。new仅仅使用这个空类对象达到一种标识作用,而不是利用这个类对象的功能。通常称这样的类对象为占位符。 
  
  C++标准规定   new   在分配内存失败的时候会抛出异常,因此在C++程序中应该通过捕捉异常来处理内存失败的情况。与之不同,传统的C语言中的malloc()函数分配内存失败时返回NULL指针。为了提供与malloc()函数一致的行为,即在内存分配失败时返回一个NULL指针,而不是抛出异常,C++还提供了   nothrow(不抛出异常)   版本的   new,即   new(nothrow)。利用   new(nothrow),可以通过判断其返回的指针值是否为NULL从而判断内存分配是否成功。

--

指针转换通常不用这个.因为如果你希望指针的类型转换,那么直接用(xxx*)这种形式或者static_cast就可以转换了,而且这种转换如果有问题编译器也会提示,如果不提示那么这种转换也是自然的,也就是说是安全的.
reinterpret_cast操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换.
例如:int *n= new int ;
       *n = 9;
  double *d=reinterpret_cast<double*> (n);
  在进行计算以后, d 包含无用值. 这是因为 reinterpret_cast 仅仅是复制 n 的比特位到 d, 没有进行必要的分析,d中打印结果也不是9。 但是如果用static_cast转换,那么d的值还是9,进行过安全的分析了

--

这是因为你的C/C++编译器进行了字对齐调整的缘故。
为了提高运行效率,有些编译器在默认的情况下做字对齐甚至双字对齐调整, 所有变量的存放起始地址都调整为字长的整数倍。即若字长32位,4字节,则所有变量的存放起始地址都是4的整数倍,而double类型更要起始在8的整数倍(双字对齐)。
于是,一个S2的结构就会这样存储(偏移量用十进制表示):

+0000 S2.c
+0004 S2.S1.a  // 本来起始地址0001, 不是4的倍数,所以调整到0004
+0008 S2.S1.b  // 调整到0008. 这个long变量实际占4字节。
+0016 S2.e     // 本来起始地址0012, 不是8的倍数,所以调整到0016
+0024 ----     // double 本身占8字节,所以到这里就24字节了。

另外,如果一个结构含有双字类型的成员,他的大小也要调整成8的倍数。所以,如果在S2最后再加上一个成员char f, 那么它总的大小将是32字节。

当然,提高运行效率的同时浪费了一些存储空间。
有些编译器有对齐的选项,可以选择字对齐,半字对齐或双字对齐。编译时如果禁止对齐调整,则所有的变量也都是连续存放的。

原文链接: https://www.cnblogs.com/qlee/archive/2011/07/07/2100516.html

欢迎关注

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

    nothrow、reinterpret_cast、位对齐、

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

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

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

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

(0)
上一篇 2023年2月8日 上午5:47
下一篇 2023年2月8日 上午5:48

相关推荐