0

I have an allocated array and need to go over all fields and compare non null values. Values in this array can also be 0 which is causing some trouble for me.

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);

Im not sure how to compare properly with NULL. What is the correct way?

6
  • In C, there is no difference between NULL and 0. Commented Nov 28, 2021 at 18:01
  • @Klas-Kenny well... 0 is just an integer literal, while NULL is ((void *)0) Commented Nov 28, 2021 at 18:04
  • You do not want to compare an int value against NULL when you really want to compare against 0. 99.44% of systems, NULL is zero, but it's not a guarantee. Also, most systems do: #define NULL ((void *) 0), so the compiler should flag the comparison of an int value against a pointer Commented Nov 28, 2021 at 18:05
  • 1
    @CraigEstey It is guaranteed, though, that a zero integer literal, or such a literal cast to a pointer type, works equivalently to NULL, even if the internal representation of a null pointer of that type is not all bits zero. Commented Nov 28, 2021 at 18:08
  • Integer variables in C are not nullable, like you may be used to in other programming languages. Commented Nov 28, 2021 at 18:09

2 Answers 2

1

Your overall design is flawed. You should not treat NULL as a catch-all zero value. NULL is a special pointer value, not simply an integer. If you compare an int against NULL, you're comparing two different types, which is not a good idea. Furthermore, you're comparing a scalar type with a pointer type, which is even worse.

Values in this array can also be 0 which is causing some trouble for me.

If this is the case, you cannot use 0 as both a value and a "mark" for "non present value". Problem is, you cannot use NULL either, because it's a different type. If you try using it, the compiler will warn you (or at least it should, if you enable warnings). At best, assigning NULL will implicitly convert it to int and result in 0 since NULL is usually defined just as ((void *)0), so it will be impossible to distinguish between NULL-ed values and valid values.

You will have to reserve one of the values between INT_MIN and INT_MAX for this purpose:

#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);
Sign up to request clarification or add additional context in comments.

Comments

0

Your allocated array elements will never be NULL. Even the memory that is freed from using free function is not NULL. IT can points to anything may be any ur own program address space or outside address space.

Ur code looks OK. The value that u did not assigned to element at index 3 can have garbage but not NULL

5 Comments

The uninitialised value can compare equal to NULL, though.
@Arkku if I do char *p=malloc(..) then it's not unitialized in a way that it must be pointing to some garbage value. IN C OR in memory there are chances more in favor of that it may be point to something even if it's garbage. So memory allocated from suceesful malloc can't have (char*)0 or NULL
Side note: I'm not totally sure, but I've rarely seen ur for your and u for you on SO [except on newbie questions]. SO != twitter? I have seen others, such as IMO, AFAIK, AFAICT, IIRC
@user786 C standard §6.3.2.3.3 defines null pointer constant as “an integer constant expression with the value 0, or such an expression cast to type void *”, so NULL can be just #define NULL 0, therefore it is entirely possible, and even likely, that a "garbage" value in memory compares equal to zero. Furthermore, the undefined value in uninitialised memory can be any bit pattern, so even if you were comparing it to a runtime null pointer (and not NULL) that had a non-zero bit representation, it's still one of the possible bit patterns that could be in memory.
And in any case the whole null speculation is besides the point, it's just one value among many. In the OP's 32-bit machine (based on allocating size * 4 memory), each garbage value is one of 2³² possible values, so there is at least 1 chance in that many to compare equal to any given constant (and not all values are equally likely to occur; in fact they can be quite deterministic in practice). And of course one could speculate that use of the uninitialised value is probably undefined behaviour, so the compiler could theoretically generate code to do whatever.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.