C 中的数组初始化是否需要空检查? C 中的数组初始化会失败吗?

Is a null check required for array initialization in C? Can array initialization in C fail?

我知道在 C 语言中,每次调用 malloc() 或 calloc() 时检查 NULL 指针是一种很好的做法。我必须为数组初始化做同样的事情吗?例如:

int sigcheck[5];
if (sigcheck == NULL) {return;}

是否需要第 2 行?如果我没记错的话,数组初始化就像在幕后调用 calloc() 一样工作,这个幕后功能是否考虑了 NULL 的可能性,还是我们自己做的 necessary/good 练习。

来自 malloc 的文档:

If the function failed to allocate the requested block of memory, a null pointer is returned.

所以你应该检查是否 malloc returns NULL 因为它可能无法为你分配请求的块(尽管这通常不太可能)。

静态分配不会在幕后调用 calloc,因为那会在 heap 而不是 stack。静态分配所需的 space 是在编译时确定的,如果无法分配足够的内存量,您的程序将无法加载。看看this question.

it is good practice to check for NULL pointer every time malloc() or calloc() is called

是的,因为这些 函数在失败时被记录为 return NULL 。这是唯一的原因。

do I have to do the same for array initialization

没有

Is line 2 necessary?

不,这没有任何意义。数组不能有空地址,它总是在某处保存一个内存位置——它最终在哪里取决于 C 调用的东西存储持续时间。在这种情况下,它具有静态存储持续时间自动存储持续时间,具体取决于它是在函数外部还是在函数内部分配。

If I'm not wrong, array initialization works like calling calloc() under the hood

你错了。 calloc 是程序员显式分配内存的一种特殊情况,因此称为 分配的存储持续时间 malloc 函数族从未 隐式或静默调用。 (除非你调用一个声称依次调用 malloc 的函数,例如 strdup。)

您可能会觉得这个问题很有趣:

数组的内存分配方式与任何其他变量类型的内存分配方式相同 - 内部没有单独的 calloc 或类似调用。行后

int sigcheck[5];

你最后的记忆是

          +---+
sigcheck: |   | sigcheck[0]
          +---+ 
          |   | sigcheck[1]
          +---+ 
           ...
          +---+
          |   | sigcheck[4]
          +---+

因此在这种情况下,无需针对 sigcheck 执行 NULL 检查。

人们感到困惑的地方是,在大多数情况下,表达式 sigcheck 将从 [= 的“5 元素数组”类型转换或“衰减” 19=]”键入“指向 int”的指针,表达式的值将是数组第一个元素的地址。人们认为 sigcheck 是一个独立于数组本身的指针对象,但事实并非如此。

当你通过malloccalloc动态分配内存时,如

int *sigcheck = calloc( 5, sizeof *sigcheck );

那么(假设请求成功)你在内存中的结果是

          +---+
sigcheck: |   | ---+
          +---+    |
            +------+
            |  
            V
          +---+
          |   | sigcheck[0]
          +---+
          |   | sigcheck[1]
          +---+ 
           ...
          +---+
          |   | sigcheck[4]
          +---+

在这种情况下,sigcheck 一个独立于数组元素的对象。而且因为malloccallocrealloc会returnNULL如果内存请求不能满足,那你 需要在 sigcheck:

上进行 NULL 检查
int *sigcheck = calloc( 5, sizeof *sigcheck );
if ( sigcheck )
{
  // do stuff
}
else
{
  // memory allocation failed, handle as appropriate
}