【问题标题】:How to check for null fields in allocated array in C如何在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 中的整数变量不可为空,就像您在其他编程语言中习惯的那样。

标签: arrays c memory null


【解决方案1】:

您分配的数组元素永远不会为 NULL。即使是从使用 free 函数中释放出来的内存也不是 NULL。 IT 可以指向任何东西,可能是您自己的程序地址空间或外部地址空间。

你的代码看起来不错。你没有分配给索引 3 的元素的值可以有垃圾但不能为 NULL

【讨论】:

  • 不过,未初始化的值可以比较等于NULL
  • @Arkku 如果我这样做 char *p=malloc(..) 那么它没有以必须指向某个垃圾值的方式进行统一化。在 C 或内存中,即使它是垃圾,它也有可能指向某些东西。所以从成功的 malloc 分配的内存不能有 (char*)0 或 NULL
  • 旁注:我不完全确定,但我很少看到ur 代表youru 代表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 是一个特殊的指针 值,而不仅仅是一个整数。如果您将intNULL 进行比较,您将比较两种不同的类型,这不是一个好主意。此外,您将标量类型与指针类型进行比较,这更糟。

这个数组中的值也可以是 0,这给我带来了一些麻烦。

如果是这种情况,您不能将0 用作值和“非现值”的“标记”。问题是,你也不能使用NULL,因为它是不同的类型。如果您尝试使用它,编译器会警告您(或者至少应该警告您,如果您启用警告)。充其量,分配NULL 会将其隐式转换为int 并导致0,因为NULL 通常被定义为((void *)0),因此无法区分NULL 值和有效值。

为此,您必须保留INT_MININT_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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    相关资源
    最近更新 更多