如何在C中检查分配数组中的空字段
Posted
技术标签:
【中文标题】如何在C中检查分配数组中的空字段【英文标题】:How to check for null fields in allocated array in C 【发布时间】:2022-01-05 19:04:42 【问题描述】:我有一个分配的数组,需要遍历所有字段并比较非空值。这个数组中的值也可以是 0,这给我带来了一些麻烦。
int size = 4;
int *numbers = (int*) malloc(size * 4);
// Fill some fields
numbers[0] = 3;
numbers[1] = 0;
numbers[2] = 6;
// Search and find min value's index
int min = 0;
for (int i = 0; i < size; i++)
if (numbers[i] != NULL)
if (numbers[i] < numbers[min]) min = i;
else
// Code if value is null here
printf("%d\n", min);
我不确定如何正确地与 NULL 进行比较。正确的方法是什么?
【问题讨论】:
在C中,NULL和0没有区别。 @Klas-Kenny 好吧...0
只是一个整数文字,而NULL
是((void *)0)
您确实不想将int
值与NULL
进行比较,而您确实想与0
进行比较。 99.44% 的系统,NULL
为零,但这不是保证。此外,大多数系统都这样做:#define NULL ((void *) 0)
,因此编译器应该标记 int
值与指针的比较
@CraigEstey 但是可以保证,零整数文字,或这种转换为指针类型的文字等价于NULL
,即使它的空指针的内部表示类型并非全为零。
C 中的整数变量不可为空,就像您在其他编程语言中习惯的那样。
【参考方案1】:
您分配的数组元素永远不会为 NULL。即使是从使用 free 函数中释放出来的内存也不是 NULL。 IT 可以指向任何东西,可能是您自己的程序地址空间或外部地址空间。
你的代码看起来不错。你没有分配给索引 3 的元素的值可以有垃圾但不能为 NULL
【讨论】:
不过,未初始化的值可以比较等于NULL
。
@Arkku 如果我这样做 char *p=malloc(..)
那么它没有以必须指向某个垃圾值的方式进行统一化。在 C 或内存中,即使它是垃圾,它也有可能指向某些东西。所以从成功的 malloc 分配的内存不能有 (char*)0
或 NULL
旁注:我不完全确定,但我很少看到ur
代表your
和u
代表you
在SO [除了关于新手问题]。 SO != twitter
?我见过其他人,例如 IMO、AFAIK、AFAICT、IIRC
@user786 C 标准第 6.3.2.3.3 节将空指针常量定义为“值为 0 的整数常量表达式,或转换为 void * 类型的表达式”,因此 NULL
可以只是#define NULL 0
,因此完全有可能,甚至很可能,内存中的“垃圾”值比较为零。此外,未初始化内存中的未定义值可以是任何位模式,因此即使您将其与具有非零位表示的运行时空指针(而不是NULL
)进行比较,它仍然是可能的位模式之一可能在内存中。
而且在任何情况下,整个空值推测都不是重点,它只是众多值中的一个。在 OP 的 32 位机器中(基于分配 size * 4
内存),每个垃圾值都是 2³² 可能值之一,因此在这么多值中至少有 1 次机会与任何给定常数进行比较(并非所有值都是同样可能发生;事实上,它们在实践中可能是相当确定的)。当然,人们可以推测使用未初始化的值可能是未定义的行为,因此编译器理论上可以生成代码来做任何事情。【参考方案2】:
你的整体设计有缺陷。您不应将 NULL
视为一个全能的零值。 NULL
是一个特殊的指针 值,而不仅仅是一个整数。如果您将int
与NULL
进行比较,您将比较两种不同的类型,这不是一个好主意。此外,您将标量类型与指针类型进行比较,这更糟。
这个数组中的值也可以是 0,这给我带来了一些麻烦。
如果是这种情况,您不能将0
用作值和“非现值”的“标记”。问题是,你也不能使用NULL
,因为它是不同的类型。如果您尝试使用它,编译器会警告您(或者至少应该警告您,如果您启用警告)。充其量,分配NULL
会将其隐式转换为int
并导致0
,因为NULL
通常被定义为((void *)0)
,因此无法区分NULL 值和有效值。
为此,您必须保留INT_MIN
和INT_MAX
之间的值之一:
#include <limits.h>
enum NOT_PRESENT = INT_MIN ;
int size = 4;
int *numbers = malloc(size * sizeof(int));
// Initialize all to NOT_PRESENT
for (int i = 0; i < size; i++)
numbers[i] = NOT_PRESENT;
// Fill some fields
numbers[0] = 3;
numbers[1] = 0;
numbers[2] = 6;
// Search and find min value's index
int min = 0;
for (int i = 0; i < size; i++)
if (numbers[i] != NOT_PRESENT)
if (numbers[i] < numbers[min]) min = i;
else
// Code if value is not present here
printf("%d\n", min);
【讨论】:
以上是关于如何在C中检查分配数组中的空字段的主要内容,如果未能解决你的问题,请参考以下文章