c - 取消引用空指针在 sizeof 操作中是否有效

标签 c sizeof dereference null-pointer

<分区>

我遇到了一段代码,对我来说应该因段错误而崩溃,但它运行顺利。有问题的代码加上相关的数据结构如下(上面有相关注释):

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]));
}

为什么会这样?我收集到 sizeof char* 将解析为给定体系结构上指针的大小,但它不应该在取消引用 NULL 时崩溃和燃烧-指针?

最佳答案

Why does this work?

这是可行的,因为 sizeof 是编译时构造,variable length arrays 除外。根本不被评估。如果我们看一下 C99 draft standard 6.5.3.4 部分 The sizeof operator 段落 2 说(强调我的):

[...] 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.

我们还在 5 段中看到以下示例,它证实了这一点:

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

在编译时确定表达式的类型,以便计算结果。我们可以通过以下示例进一步证明这一点:

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

不会增加 x,这非常简洁。

更新

正如我在 my answer 中指出的那样至 Why does sizeof(x++) not increment x? sizeof 有一个异常(exception),它是编译时操作,即它的操作数是可变长度数组 (VLA)。尽管我之前没有指出上面 6.5.3.4 的引述确实是这样说的。

尽管在 C11 中而不是 C99 中未指定在这种情况下是否评估 sizeof

另外,请注意这个问题有一个 C++ 版本:Does not evaluating the expression to which sizeof is applied make it legal to dereference a null or invalid pointer inside sizeof in C++? .

关于c - 取消引用空指针在 sizeof 操作中是否有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19785518/

相关文章:

c++ - 迭代器取消引用中的段错误

c - 访问结构指针的成员时取消引用指向不完整类型的指针

c - gethostbyname 失败,主机名来自 gethostbyaddr,成功了

c - 不使用 strtok 标记一行

c++ - 我可以在不创建结构实例的情况下获得结构字段的大小吗?

c - 字符数组的大小和字符指针的大小

c - 在c中将ByteArray写入文件

c - 更好地理解 c 中可变参数的类型提升

c++ - sizeof(T) * CHAR_BIT 是否保证位大小?

c - 将地址写入指针