是否需要检查没有 malloc() 声明的 C 数组的有效性?

Do C arrays declared without malloc() need to be checked for validity?

(如果有人有建议,我会改写标题,我知道这有点尴尬。)

在使用 malloc() 为 C 中的动态数组分配内存时,我知道通过验证指针不为 NULL 来检查调用是否成功。是否需要对 C 中显式声明的数组执行相同的检查,例如在以下示例中(取自 this question)?

char arrinit[5];
char (*arrinit_two)[5] = &arrinit;

简而言之:没有!

编译器将确保您的数组有足够的静态定义内存。

通常(取决于您声明它们的方式),它们将分配在堆栈上,当堆栈上没有足够的剩余内存时,您的程序可能会在您进行任何检查之前崩溃,或者您将无法采取任何补救措施。

顺便说一句:无论如何,你也不会得到 NULL 值,因为系统会给你一些地址值,即使没有剩余内存(或者它之前已经崩溃)。

当然有一种情况,你应该小心:当你想分配非常大的内存(一个大数组)时,你应该这样做分配。在许多系统上,进程的堆栈大小受到限制,因此当您在堆栈上分配大量内存(编译器为您完成)时比使用 malloc 时(因为有不是相同的限制)。

当然,在今天的计算机上,这意味着,在它产生任何影响之前,您可以拥有至少一些 MB 的数组。对于小于 1MB 的数组,您无需费心。

不,如果指针指向堆栈变量则不需要检查,我想你的意思是

int  array[5] = {1, 2, 3, 4, 5};
int *pointer;

pointer = array;
if (pointer != NULL) /* will always be true */
...

有编译器警告会警告

if (array != NULL)

并告诉你这个条件总是成立的。

如果你声明一个指针并指向它,比如

int *pointer = array;

那么编译器将无法警告你,但条件仍然不能为假,因为数组是在创建函数堆栈帧时分配的,所以如果不能分配数组,那么它将是无法调用函数。

如果你定义一个数组对象,检查它是否分配成功是不必要的或不可能的。

如果用 static storage duration 定义(即在任何函数体外部定义或用 static 关键字定义),则所需内存量为在编译时确定,并在加载程序时分配。如果没有足够的空间,根据系统的不同,您的程序很可能无法执行。

如果它是在没有 static 关键字的函数中定义的,那么内存将在调用该函数时或在包含它的块的入口处分配。如果 that 分配失败,则行为未定义。最常见的是,该程序将死于 "stack overflow" 或类似的东西。该语言没有提供一种方法来提前检测这样的分配是否会成功,或者在它失败之后检测。

这意味着像这样的东西:

{
    char arr[5];
    if (arr != NULL) ...
}

几乎肯定不会检测到任何分配失败;已声明对象的地址始终为非空。