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
是一个独立于数组本身的指针对象,但事实并非如此。
当你通过malloc
或calloc
动态分配内存时,如
int *sigcheck = calloc( 5, sizeof *sigcheck );
那么(假设请求成功)你在内存中的结果是
+---+
sigcheck: | | ---+
+---+ |
+------+
|
V
+---+
| | sigcheck[0]
+---+
| | sigcheck[1]
+---+
...
+---+
| | sigcheck[4]
+---+
在这种情况下,sigcheck
是 一个独立于数组元素的对象。而且因为malloc
、calloc
、realloc
会returnNULL
如果内存请求不能满足,那你做 需要在 sigcheck
:
上进行 NULL
检查
int *sigcheck = calloc( 5, sizeof *sigcheck );
if ( sigcheck )
{
// do stuff
}
else
{
// memory allocation failed, handle as appropriate
}
我知道在 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
是一个独立于数组本身的指针对象,但事实并非如此。
当你通过malloc
或calloc
动态分配内存时,如
int *sigcheck = calloc( 5, sizeof *sigcheck );
那么(假设请求成功)你在内存中的结果是
+---+
sigcheck: | | ---+
+---+ |
+------+
|
V
+---+
| | sigcheck[0]
+---+
| | sigcheck[1]
+---+
...
+---+
| | sigcheck[4]
+---+
在这种情况下,sigcheck
是 一个独立于数组元素的对象。而且因为malloc
、calloc
、realloc
会returnNULL
如果内存请求不能满足,那你做 需要在 sigcheck
:
NULL
检查
int *sigcheck = calloc( 5, sizeof *sigcheck );
if ( sigcheck )
{
// do stuff
}
else
{
// memory allocation failed, handle as appropriate
}