转:为什么C++中空类和空结构体大小为1?
参考:http://www.spongeliu.com/260.html
对于结构体和空类大小是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,应该得到数组的另一个索引。如下代码:
1 |
T array[5]; |
上面的代码是一种指针运算,将两个指针相减,编译器作出如下面式子所示的动作:
diff = ((char *)&array[3] - (char *)&array[2]) / sizeof T;
式子应该不难懂把,很明显的一点就是这个式子的计算依赖于sizeof T。虽然上面只是一个例子,但是基本上所有的指针运算都依赖于sizeof T。
好,下面我们来看,如果允许不同的对象有相同的地址将会引发什么样的问题,看下面的例子:
1 |
&array[3] - &array[2] = &array[3] - &array[1] |
我们可以看到,在这个例子中,如果每个对象都拥有相同地址,我们将没有办法通过指针运算来区分不同的对象。还有一个更严重的问题,就是如果 sizeof T是0,就会导致编译器产生一个除0的操作,引发不可控的错误。
基于这个原因,如果允许结构体或者类的大小为0,编译器就需要实现一些复杂的代码来处理这些异常的指针运算。
所以,C++标准规定不同的对象不能拥有相同的地址。那么怎样才能保证这个条件被满足呢?最简单的方法莫过于不允许任何类型的大小为0。所以编译器为每个空类或者空结构体都增加了一个虚设的字节(有的编译器可能加的更多),这样这些空类和空结构的大小就不会是0,就可以保证他们的对象拥有彼此独立的地址。
转:为什么C++中空类和空结构体大小为1?的更多相关文章
- 为什么C++中空类和空结构体大小为1?(转载)
原文链接:http://www.spongeliu.com/260.html 对于结构体和空类大小是1这个问题,首先这是一个C++问题,在C语言下空结构体大小为0(当然这是编译器相关的).这里的空类和 ...
- C++中的空类与空结构体大小
今天面试遇到了一个很有意思的问题,即空结构体在C++中所占的内存大小是多少?参见如下代码: #include <iostream> struct S0 { }; int main() { ...
- Windows下struct和union字节对齐设置以及大小的确定(一 简介和结构体大小的确定)
在windows下设置字节对齐大小的方式,目前我了解有三种: 1. 在编译程序时候的编译选项 /Zp[n],如 cl /Zp4 表示对齐大小是4字节: 2. 预处理命令 #pragma pack ...
- C语言中结构体大小计算
1.普通结构体 struct student { char sex; char a; char b; int age; char name[100]; }; 该结构体大小为108 解答:1.先算str ...
- struct结构体大小的计算(内存对齐)
本次实验环境 环境1:Win10, QT 5.12 一. 背景 当普通的类型无法满足我们的需求的时候,就需要用到结构体了.结构体可衍生出结构体数组,结构体还可以嵌套结构体,这下子数据类型就丰富多彩了, ...
- C++ c++与C语言的区别(空结构体)
//区别⑨:空结构体声明(C++版本) #include<iostream> using namespace std; struct A{}; class B{}; void main() ...
- EF:根据实体类生成表结构SQL
根据实体类生成表结构SQL: PM> Enable-Migrations -ProjectName Domain -StartUpProjectName Handler -Force PM> ...
- java通过反射取得一个类的完整结构
首先我们在person包中新建一个Person.java: package person; import sex.Sex; public class Person{ private String na ...
- QT类的继承结构
QT类的继承结构 QT的类 core 数据集合 QString 几何类 QPoint QSize QRectangle 系统类 QColor QFont QImage QIcon QCursor QB ...
随机推荐
- PHP之分页类
<?php /** * Created by PhpStorm. * User: Administrator * Date: 2016/6/22 * Time: 21:37 */ Class P ...
- asp.net 页面跳转传值的几种方式
参考地址: http://blog.csdn.net/zzzzzzzert/article/details/8486143 protected void Button1_Click(object se ...
- Hangover 分类: POJ 2015-06-11 10:34 12人阅读 评论(0) 收藏
Hangover Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 108765 Accepted: 53009 Descr ...
- 使用 JavaScript
我们要用 JavaScript,但是把它写在哪里呢? 这里 ↘ 1. HTML 页面中 . 2. 单独的一个文件中,文件后缀名是“.js”. ——————————————————— ...
- libevent系列之一——libevent介绍
摘自:http://libevent.org/ libevent概述:一套事件通知库. libevent提供一套机制完成以下功能:当指定的事件发生在file descriptor时或者超时后执行一个回 ...
- JAVA的名词释义
JDK : Java Development Toolkit (java 开发工具包). JDK是整个JAVA的核心,包括了java运行环境(Java Runtime Envirnmet),一堆jav ...
- 【leetcode❤python】 36. Valid Sudoku
#-*- coding: UTF-8 -*-#特定的九个格内1-9的个数至多为1#依次检查每行,每列,每个子九宫格是否出现重复元素,如果出现返回false,否则返回true.class Solutio ...
- [转]SIP穿越NAT&FireWall解决方案
原文链接(也是转载)http://blog.csdn.net/yetyongjin/article/details/6881491.我修改了部分错字. SIP从私网到公网会遇到什么样的问题呢? 1 ...
- 【CSS】最全的CSS浏览器兼容问题
CSS对浏览器的兼容性有时让人很头疼,或许当你了解当中的技巧跟原理,就会觉得也不是难事,从网上收集了IE7,6与Fireofx的兼容性处理方法并 整理了一下.对于web2.0的过度,请尽量用xhtml ...
- VBA中操作XML
OFFICE2007之后使用了OpenXml标准(伟大的改变),定制文本级的Ribbon可以通过修改压缩包内的xml文件来实现. 先学习一下VBA中操作XML的方法 先引用Microsoft XML ...