关于sizeof,对空指针sizeof(*p)可以吗?
C/C++的sizeof在动态分配内存时经常用到,但之前一直没怎么关注它的具体机制。今天在为一个复杂声明的指针分配内存时,想起来要了解一下sizeof到底是什么?
先抛个问题:
程序运行过程中对空指针解引用,程序会直接core。那么sizeof对一个空指针“解引用”行不行?(int p=nullptr; size_t iSize=sizeof(*p))。比如如下应用场景:
int (*p)[10] = nullptr;/*p是一个指向有10个int型元素的数组的指针*/
如果要分配5个数组的空间,用malloc(5 * 10 * 4)吗?还是用malloc(5 * 10 * sizeof(int))?从结果来看,都能实现。但如果上述数组的类型、大小可能会变化,比如数组大小变成11,就得在声明和分配处分别修改代码,难免会改漏。一种可行的方式是用一个宏来表示数组大小。这里,我想换个方式,指针声明时明确了数组大小,所以能不能在malloc的时候用sizeof计算出指针的元素大小(即数组大小,注意此时指针是空的),从而只需要在声明时说明数组大小,避免在malloc的时候再关心数组多大?
答案是可以。这条语句是合法的:p = (int (*)[10])malloc(5 * sizeof(*p))。这里sizeof的参数p是空指针,下面解释为什么这里的*p是合法的。
什么是sizeof,以及它的机制?
sizeof的一般使用形式都是sizeof( xx ),所以sizeof是不是一个函数呢?答案是看情况。有些编程语言里,sizeof是函数,这个不细讲(因为我也不会几种编程语言)。在C/C++里,sizeof不是函数,是一个内置的运算符或操作符,跟“ + - * / ”一样的运算符。sizeof可以返回一个类型或者对象所占用的内存空间字节数。
而且关键的,sizeof的参数是类型(如sizeof(int)),或者是具体某个变量的类型(如int* p, sizeof(*p),这里的参数是int*)。sizeof是编译器在编译阶段解析并完成计算的,运行阶段并没有sizeof。所以对一个空指针执行sizeof(*p),实际上等价于对p指向的对象的类型作sizeof,而且是在编译阶段就完成了,没解引用,所以是合法的。
这里分享个《C专家编程》第2章的例子:
a = N * sizeof * q;/*这里有几个乘号?答案是1个。sizeof操作符把指针q指向的东西作为操作数(即*q)*/
有意思的是上面这个例子,sizeof的参数没用括号,在函数调用里这显然不合法,但sizeof是操作符就是任性。当sizeof的操作数是类型名时,两边必须加括号,但操作数如果是变量则可以不加括号。
apple = sizeof(int) * a;/*这个例子书上没给答案。事实上,这里先计算sizeof(int),然后再乘以a的值*/
最后回到开篇的问题,给p分配内存的另一种方式:
typedef int pPtr[10];/*为了方便我们用自定义类型*/
pPtr* p=nullptr;/*相当于int (*p)[10] = nullptr;*/
p = (int (*)[10])malloc(5 * sizeof(*p))。
这里sizeof对空指针操作了*p,实际并未解引用,而是在编译阶段计算出指针p指向的类型的大小,所以是合法的。
关于sizeof,对空指针sizeof(*p)可以吗?的更多相关文章
- sizeof(int *) 和 sizeof(int)型的大小问题
小问题,暂时记录注意一下 printf("sizeof(int): %d\n", (int)sizeof(int)); printf("sizeof(int ...
- sizeof()与Marshal.SizeOf()的不同
在.NET中一般都是通过sizeof()或Marshal.SizeOf()来获取数据类型的大小,来简要地看一下它们二者有何不同. sizeof() sizeof()在MSDN中的介绍是,在编译时获得一 ...
- #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
原文 功能: 首先,sizeof(int)肯定是2的次方数,比如32位是4,64位是8 ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) 的意思就 ...
- 虚函数指针sizeof不为sizeof(void*)
ref:http://bbs.csdn.net/topics/360249561 一个继承了两个虚基类又增加了自己的一个虚函数pif的类,sizeof(指向pif的指针)竟然是8(X86).我是从这里 ...
- 数组类型与sizeof与指针的引用
以char类型为例: char a[100]; //a类型为char[100] &a类型为 char (*)[100] *a类型为char char *p = a; ...
- sizeof运算符、malloc函数及free函数
一.sizeof运算符的用法 1.sizeof运算符给出某个类型或变量在内存中所占据的字节数. int a; sizeof(a)=4; //sizeof(int)=4; double b; si ...
- 聊聊 C 语言中的 sizeof 运算
聊聊 sizeof 运算 在这两次的课上,同学们已经学到了数组了.下面几节课,应该就会学习到指针.这个速度的确是很快的. 对于同学们来说,暂时应该也有些概念理解起来可能会比较的吃力. 先说一个概念叫内 ...
- c/c++中关于sizeof、strlen的使用说明
sizeof: 一般指类型.变量等占用的内存大小(由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小) strlen: c字符串的长度(参数必须是字符型指针 char*,当数组名作 ...
- C语言中的sizeof()
sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着"辛苦我一个,幸福千万人"的伟大思想,我决定将其尽可能详细的总结一下. 但当我总结的时候才发现,这个 ...
随机推荐
- JS——变量声明、变量类型、命名规范
变量声明: JavaScript是一种弱类型语言,它的变量类型由它的值来决定,var是变量声明. 变量类型: 基本类型:number.string.boolean(布尔类型:var a=true/fa ...
- 讲明白combineByKey()算子,不是谈源码
简单介绍 combineByKey()是最通用的对key-value型rdd进行聚集操作的聚集函数(aggregation function).类似于aggregate(),combineByKey( ...
- arcgis python 保存当前窗口图形为jpg
1,第一步打开arcgis 将图形加载进去 第二步,将要保存的图形调到合适的比例尺,然后点击下面按钮 第三步,将写好的python 语句放到里面去: import arcpy mxd = arcpy. ...
- 如何移除网站Response Headers中的X-Powered-By信息?
X-Powered-By是网站响应头信息其中的一个,出于安全的考虑,一般会修改或删除掉这个信息. 如果你用的node.js express框架,那么X-Powered-By就会显示Express.如果 ...
- Python+Selenium与Chrome如何进行完美结合
zhuan:http://blog.51cto.com/starpoint/2102975?cid=704621 使用WebDriver在Chrome浏览器上进行测试时,需要从http://chrom ...
- 如何检查SQL Server索引填充因子
假如您有一个盛满水的玻璃杯,您要尝试再向这个玻璃杯中加水.结果会怎样呢?水会溢出来. SQL Server 的情况也是如此.当索引页填充满时,如果尝试添加新行,则 SQL Server 会将大约一半的 ...
- .net后台使用post方式对指定地址的方法传值并且获取结果的方法
/// <summary> /// .net 后台 post http地址请求 /// </summary> /// <param name="uri" ...
- noip模拟赛#45
T1:n<=1e6,求最小的区间包含(1,m)的所有数. =>双指针扫一遍即可 #include<cstdio> #include<cstring> #includ ...
- CentOS lvm
1.创建PVpvcreate /dev/sdb /dev/sdc或pvcreate /dev/sdb1 /dev/sdc1 2.查看PVpvdisplay 3.创建VGvgcreate vgdata ...
- xpath定位和css定位对比
xpath定位和css定位对比 实际项目中使用较多的是xpath定位和css定位.XPath是XML文档中查找结点的语法,换句话就是通过元素的路径来查找这个元素.xpath比较强大,而css选择器 ...