被取消引用空指针的sizeof运算有效 [英] Is dereferencing null pointer valid in sizeof operation

查看:117
本文介绍了被取消引用空指针的sizeof运算有效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到$ C $的片段C,它给了我应该用的分段故障的崩溃,但它工作顺利。问题加上相关的数据结构中的code如下(右发现上述相关注释):

  typedef结构{
  双长度;
  unsigned char型nPlaced;
  unsigned char型路径[0];
}
RouteDefinition * Alloc_RouteDefinition()
{
  //注:本+ nBags * sizeof的..绝招拓展,在RouteDefinition路径[0]数组
  //的路径[nBags]数组
  RouteDefinition * DEF = NULL;
  回报(RouteDefinition *)malloc的(的sizeof(RouteDefinition)+ nBags * sizeof的(def->路径[0]));
}

为什么这项工作?我收集了的的sizeof 的的的字符的*将解析为给定的架构指针的大小,但它不应该和好如初,同时取消引用 NULL 终场?


解决方案

  

为什么这项工作?


这是因为工作的的sizeof 的是一个编译时间结构,用的 是不是在所有评估变长数组。如果我们看一下 C99标准草案部分 6.5.3.4 sizeof操作符的段落的 2 的说(的重点煤矿的):


  

...]的大小是从操作数的类型来确定。结果是整数。 如果操作数的类型是可变长度数组类型,操作数被评估;否则,操作数不计算,结果是整型常量。


我们也看到第下面的示例中的 5 的这证实了这一点:

 双* DP =页头(sizeof的* DP);
       ^^^ ^
                          |
                          这不是使用未初始化的指针

在编译时的键入的,以便计算结果来确定除权pression的。我们可以用下面的实施例进一步证明这一点:

  INT X = 0;
的printf(%祖\\ N的sizeof(X ++));

这将不会增加 X ,这是pretty整洁。

更新

正如我注意到,在我的回答来的为什么的sizeof(X ++),不增加x?有一个例外的sizeof 是一个编译时的操作,这是当它的操作数是可变长度阵列( VLA 的)。虽然我没有previously指出这点从报价 6.5.3.4 上面并说这一点。

虽然在C11相对于C99是不确定是否的sizeof 评估或未在这种情况下。

此外,注意,是一个C ++版本的quesiton的:不评估前pression到sizeof的应用化妆它的法律取消引用内部null或无效的指针的sizeof在C ++?

I've come across a snippet of code that to me should crash with a segmentation fault, and yet it works without a hitch. The code in question plus relevant data structure is as follows (with associated comment found right above):

typedef struct {
  double length;
  unsigned char nPlaced;
  unsigned char path[0];
}


RouteDefinition* Alloc_RouteDefinition()
{
  // NB: The +nBags*sizeof.. trick "expands" the path[0] array in RouteDefinition
  // to the path[nBags] array
  RouteDefinition *def = NULL;
  return (RouteDefinition*) malloc(sizeof(RouteDefinition) + nBags * sizeof(def->path[0]));
}

Why does this work? I gather that the sizeof the char* will resolve to the size of the pointer on the given architecture, but shouldn't it crash and burn while dereferencing a NULL-pointer?

解决方案

Why does this work?

This works because sizeof is a compile time construct, with the exception of variable length arrays is not evaluated at all. If we look at the C99 draft standard section 6.5.3.4 The sizeof operator paragraph 2 says(emphasis mine):

[...] The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

we also see the following example in paragraph 5 which confirms this:

double *dp = alloc(sizeof *dp);
       ^^^                ^
                          |                                 
                          This is not the use of uninitialized pointer 

At compile time the type of the expression with be determined in order to compute the result. We can further demonstrate this with the following example:

int x = 0 ;
printf("%zu\n", sizeof( x++ ));

which won't increment x, which is pretty neat.

Update

As I note in my answer to Why does sizeof(x++) not increment x? there is an exception to sizeof being a compile time operation and that is when it's operand is a variable length array(VLA). Although I did not previously point it out the quote from 6.5.3.4 above does say this.

Although in C11 as opposed to C99 it is unspecified whether sizeof is evaluated or not in this case.

Also, note there is a C++ version of this quesiton: Does not evaluating the expression to which sizeof is applied make it legal to dereference a null or invalid pointer inside sizeof in C++?.

这篇关于被取消引用空指针的sizeof运算有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆