为什么C++中空类和空结构体大小为1?

转载 2015年07月10日 21:29:46

这篇文章是一篇译文,跟上一篇文章相呼应的,原文在这里

对于结构体和空类大小是1这个问题,首先这是一个C++问题,在C语言下空结构体大小为0(当然这是编译器相关的)。这里的空类和空结构体是指类或结构体中没有任何成员。

在C++下,空类和空结构体的大小是1(编译器相关),这是为什么呢?为什么不是0?

这是因为,C++标准中规定,“no object shall have the same address in memory as any other variable” ,就是任何不同的对象不能拥有相同的内存地址。 如果空类大小为0,若我们声明一个这个类的对象数组,那么数组中的每个对象都拥有了相同的地址,这显然是违背标准的。

但是,也许你还有一个疑问,为什么C++标准中会有这么无聊的规定呢?

当然,这样规定显然是有原因的。我们假设C++中有一个类型T,我们声明一个类型T的数组,然后再声明一个T类型的指针指向数组中间某个元素,则我们将指针减去1,应该得到数组的另一个索引。如下代码:

T array[5];

int diff = &array[3] - &array[2];

//diff  = 1



上面的代码是一种指针运算,将两个指针相减,编译器作出如下面式子所示的动作:

diff = ((char *)&array[3] - (char *)&array[2]) / sizeof T;

式子应该不难懂把,很明显的一点就是这个式子的计算依赖于sizeof T。虽然上面只是一个例子,但是基本上所有的指针运算都依赖于sizeof T。

好,下面我们来看,如果允许不同的对象有相同的地址将会引发什么样的问题,看下面的例子:

&array[3] - &array[2] = &array[3] - &array[1]

    = &array[3] - &array[1]

   = &array[3] - &array[0]

   =0



我们可以看到,在这个例子中,如果每个对象都拥有相同地址,我们将没有办法通过指针运算来区分不同的对象。还有一个更严重的问题,就是如果 sizeof T是0,就会导致编译器产生一个除0的操作,引发不可控的错误。

基于这个原因,如果允许结构体或者类的大小为0,编译器就需要实现一些复杂的代码来处理这些异常的指针运算。

所以,C++标准规定不同的对象不能拥有相同的地址。那么怎样才能保证这个条件被满足呢?最简单的方法莫过于不允许任何类型的大小为0。所以编译器为每个空类或者空结构体都增加了一个虚设的字节(有的编译器可能加的更多),这样这些空类和空结构的大小就不会是0,就可以保证他们的对象拥有彼此独立的地址。

返回值为结构体,返回值可能为空时候的处理情况

适用情况: (1) 函数的返回类型是一个结构体(如StructA),而这个返回值有可能为空。 此时不能直接返回null或者0,否则编译器会报错:无法将null或者0隐式转成结构体StructA,因...
  • u011926026
  • u011926026
  • 2017年04月11日 15:52
  • 655

C/C++空结构体,空数组,空类作用

原文地址:http://blog.sina.com.cn/s/blog_93b45b0f01015s95.html作者:刻卜浪兴 我们经常会遇到这些问题: (1)C++中定义一个空类,...
  • feitianhu213
  • feitianhu213
  • 2013年08月09日 19:54
  • 2247

空结构体与空指针的大小

今天面试遇到了一个很有意思的问题,即空结构体在C++中所占的内存大小是多少?参见如下代码: #include struct S0 { }; int main() { std::...
  • smilesundream
  • smilesundream
  • 2017年07月09日 22:21
  • 262

【C++】计算struct结构体占用的长度

关于结构体和类所占用的长度计算方式介绍。 struct A { char a[5]; int b; short int c; }structA; 在上例中,要计算 size...
  • nisxiya
  • nisxiya
  • 2014年03月29日 02:21
  • 2044

C++基础---结构体(struct)

1. 结构体(struct) 1.1 结构体的概念 结构体(struct):是由一系列具有相同类型或不同类型的数据构成的数据集合,叫做结构。 结构体(struct):是一种复合数据类型,结构类型。...
  • cainv89
  • cainv89
  • 2015年10月12日 01:19
  • 6484

【C++ -> 容器初始化】结构体嵌套复杂结构初始化

案例简述最近在设计数据结构时,数据之间较为复杂,数据结构如下:typedef struct tagDataInfo { long offs; // 索引 ...
  • changqing5818
  • changqing5818
  • 2017年11月13日 18:34
  • 201

C++结构体占用内存大小浅析

以下是结合之前计算机组成原理的知识,实践总结的两条规律
  • Jacketinsysu
  • Jacketinsysu
  • 2016年04月02日 16:54
  • 914

结构体类型struct(c++)

本文简单介绍了定义结构体的三种形式,嵌套结构体,结构体变量的初始化,结构体变量成员的引用方法,以及结构体指针...
  • sinat_34927324
  • sinat_34927324
  • 2016年12月23日 20:04
  • 411

C/C++结构体struct详解

结构体定义 typedefstruct 用法详解和用法小结 typedef是类型定义的意思。typedef struct 是为了使用这个结构体方便。 具体区别在于: 若struct n...
  • itguangit
  • itguangit
  • 2015年11月30日 19:07
  • 9141

结构体数组(C++)

1.定义结构体数组 和定义结构体变量类似,定义结构体数组时只需声明其为数组即可。如: struct Student{ int num; char name[20]; ch...
  • QianShouYuZhiBo
  • QianShouYuZhiBo
  • 2013年08月11日 22:12
  • 8437
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:为什么C++中空类和空结构体大小为1?
举报原因:
原因补充:

(最多只允许输入30个字)