为什么这个 'sizeof()' 返回是 C 中的 0 个字节?

问题描述

我的问题是关于 sizeof 和内存分配。当我学习 C 和测试类型值时,我尝试了以下代码

#include <stdio.h>

int main(void) {
char vec[0];
vec[0] = 1;
printf("\n SIZEOF: %li",sizeof(vec));
printf("\n VEC[0]: %li",vec[0]);
}

输出是:

> SIZEOF: 0

> VEC[0]: 1

为什么“vec[0]”的大小为“0 字节”,即使我添加了值“vec[0] = 1”? (如果我不添加此值,只需声明向量“char vec[0] 或 int vec[0]”,输出相同)。

瑞克。非常适合您的时间。

解决方法

vec 被定义为一个大小为零元素的数组。零元素的大小为零,这似乎是明智的。为 vec[0] 赋值会覆盖某处的内存。

,

这段代码

char vec[0];
vec[0] = 1;

调用未定义的行为。

你不能声明一个元素为零的数组。

来自 C 标准(6.7.6.2 数组声明符)

1 除了可选的类型限定符和关键字 static, [ 和 ] 可以分隔表达式或 *。如果它们分隔表达式 (指定数组的大小),表达式应具有 整数类型。 如果表达式是一个常量表达式,它应该 具有大于零的值。 元素类型不应是 不完整或函数类型。可选的类型限定符和 关键字 static 应仅出现在函数声明中 具有数组类型的参数,然后仅在最外面的数组中 类型推导。

注意在这些 printf 调用中使用了不正确的转换说明符

printf("\n SIZEOF: %li",sizeof(vec));
printf("\n VEC[0]: %li",vec[0]);

对于类型为 sizeof 的运算符 size_t 返回的值,您应该使用转换说明符 %zu,对于类型为 char 的对象,您应该使用转换说明符 %c

关于你的问题

为什么即使我添加了值“vec[0] = 1”,“vec[0]”的大小也是“0字节” ? (如果我不添加这个值,只需声明向量“char vec[0] 或 int vec[0]" 输出相同)。

然后编译器应该发出与数组无效声明相关的消息。

至于输出,因为数组不是可变长度数组,所以表达式 sizeof( vec ) 的值在编译时计算。编译器看到元素数等于 0 并将表达式 sizeof( vec ) 计算为 0 * sizeof( char )。因此这个表达式总是产生与数组元素类型无关的 0

,

数组必须定义为正大小。

您创建的大小为 0,这是违反约束的,因此您的代码显示 undefined behavior

,

当您编写 N 时,您实际上并未填充长度为 0 0,1,2 ... N-1 的“数组”中的位置。

请记住,当您声明长度为 0 的数组时,其有效索引为 int data[3] = { 1,2,3 }; data[10000] = 10; 。如果数组大小为 vec[0],则有效索引是什么?一个都没有!

这是同一种未定义的行为:

vec

写入 {{1}} 可能适用于您的系统,但它仍然不是属于 {{1}} 的内存。