我正在为指针数组分配内存。结果具有固定数量的项目,我希望所有项目都初始化为NULL
。
char **result = (char **)calloc(12, sizeof(char *));
我现在可以确定result[0]
到result[11]
的元素是NULL
吗?
答案 0 :(得分:4)
作为0
- 通过执行
p
指针的值
memset(p, 0, sizeof(p));
没有必要等于做
p = NULL;
在每个平台上,您都可以安全地做到:
SomeType ** result = malloc(12 * sizeof(*result));
if (NULL != result)
{
for (size_t i = 0; i < 12; ++i)
{
result[i] = NULL;
}
}
您可以将其包装在宏中,如下所示:
#define ALLOCARRAY(result, size) \
do { \
result = malloc(size * sizeof(*result)); \
if (NULL != result) \
{ \
for (size_t i = 0; i < size; ++i) \
{ \
result[i] = NULL; \
} \
} \
} while (0)
然后像这样使用宏:
#include <stdlib.h>
[...]
SomeType ** result = NULL;
ALLOCARRAY(result, 12);
if (NULL == result)
{
/* Handle error here. */
}
else
{
/* Use array here. */
/* Free array. */
free(result);
}
答案 1 :(得分:3)
calloc()
将分配的空间设置为所有位 - 零,但在某些实现中空指针可能不是位零。对于便携式解决方案,您仍需要手动将它们设置为空指针。
for (int i = 0; i < 12; i++)
{
result[i] = NULL;
}
答案 2 :(得分:3)
这个问题,IMO,有点夸张。是的,绝对正确的是某些机器在某处不使用全位零模式为null,就像有机器具有(或历史上)奇数球字节大小为9或11位的机器一样。并且知道这对于从另一个不知道这一点的程序员那里获得免费啤酒来说偶尔会有用,但不会超过那个。 (当然,这对编写C标准或编译器的人来说非常有用。)
我愿意成为这个线程中的几个读者/评论者已经工作,或者在这样的机器上运行;但是你必须明白,一般来说,堆栈流量回答人群有些偏向于已经看过并完成所有事情的大师类型。 (顺便说一句,我不算这个群体。)世界上绝大多数“普通”C程序员(他们正在编写C代码以在常见的Windows / Mac / Linux / Unix /(*)下运行*)平台,或编写嵌入式代码,几乎可以在任何常见的嵌入式架构平台上运行)在其生命周期中永远不会在calloc没有为您提供有效 NULL指针的系统上工作,并且很少有人会在无符号字符不是8位宽的机器上工作 - 并且几乎和他们的代码永远不会移植到这些系统之一的几率一样好。
所以,虽然我完全同意理解标准的技术细微差别是一件好事 - 知道更多永远不会伤害 - 我认为你还必须运用一些常识来决定代码需要担心哪种类型的可移植性关于。除非您实际上可以访问具有奇怪字节大小的机器或非零位空指针,否则您实际上无法测试代码的可移植性(更不用说您依赖的任何库)了条件,除非你知道你正在编写需要广泛移植的代码,否则你的精神能量最好花在查找和修复系统中更平凡的错误上。
(**)我是否还需要在此列表中提及VMS或被狂热者扑灭? :)
答案 3 :(得分:2)
这在C 2011标准的非规范性脚注296中明确说明:“请注意,[calloc将所有位初始化为零]不必与浮点零或空指针常量的表示相同。”