14

How can I check to see if an element in an array is empty in C?

if(array[i] == NULL) 

Doesn't seem to work.

6
  • 2
    What doesn't work? That one line of code isn't of much help. What is array, where is it initialized? Commented Nov 14, 2010 at 17:59
  • 3
    Please define what you mean by "doesn't work" -- does it not compile? Is the runtime behavior different than you expected? (Maybe you forgot to initialize the array contents to NULL first?) Commented Nov 14, 2010 at 18:00
  • I think this is the problem cdhowie as I'm used to java everything is initialised to null. What is the default initialization of an element in C. Commented Nov 14, 2010 at 18:03
  • 2
    @Alex: Nothing. Or rather garbage. C doesn't do any initialization for you, if you don't either, then it's just whatever happens to be present in memory at that point of time. Commented Nov 14, 2010 at 18:04
  • Try using memset next time. It's not used by default because you may need to put something else there and don't need this overhead. Commented Nov 14, 2010 at 18:06

4 Answers 4

31

What do you mean with empty?

When a C program is executed, variables that you don't explicitly initialize have got unpredictable values.

You need to set all of your array cells to NULL (or to 0, or to whatever value represents emptyness in your program logic) and then you can check it in the way you did:

int *array[3] = { NULL, NULL, NULL }; // array of three "empty" pointers

...

for( i = 0; i < 3; ++ i ) {
  if( array[i] == NULL ) {
    // i-th cell is "empty"
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

+1 for pointing out the lack of initialization bug -- probably what's going on here.
int *array[3] = { NULL } should suffice to nullify all the array elements.
@Uila: in practice yes, but I think it might be less clear and misleading, since that only work to initialize an array to 0. You cannot use such shortcut to initialize all the elements of an array to 1, and moreover NULL might be different from 0.
1

Question answer:

What you posted is the correct code.

Elaboration:

If it "doesn't seem to work", perhaps the problem does not lie at this location in your code. If you would post a more complete example of what you have, the code's expected behavior and actual behavior, we may be able to help you.

Comments

1

Assuming that array is indeed an array of pointers, the single line of code provided should indeed verify that element at index i is NULL.

Note however that if you array is not properly initialized (ie: provide an initial value to each cell), the array most probably contains garbage and your condition will most probably end up being false.

Comments

-1

At first I was thinking, "They need to use pointer arithmetic so the object doesn't get auto de-referenced by the "[ ]" operator.

Then I realized, no... Arrays in C don't have null slots.

I conclude, the asker is:

  1. Using an array of structs.

  2. Using it as if it were an array of pointers to structs.

peoro's solution is pretty good. But I would recommend modifying it a bit. Add a ".exists" property to your struct if you want to do it the lazy/simple way. Simple is not a bad thing, the more parts in a machine the more things that can go wrong.

Code below demonstrates two things:

  1. Faking a sparse array using peoro's solution with .exists flag modification.

  2. An actual sparse array using double pointers.


#include<stdlib.h> //:for: malloc(...)
#include<stdlib.h> //:for:   free(...)
#include <stdio.h> //:for: printf(...)
int main( void ){
    printf("[BEG:main]\n");

    typedef struct MyStruct{
        int whatever;
    } MyStruct;

    int        num = 16; //:sixteen_elements

    //:USE CALLOC HERE! If you use malloc you'll
    //:end up with something even worse than
    //:null pointers... Pointers that point to
    //:random places in memory. 
    //:
    //: It will make your:
    //: if( arr[i] != NULL )... 
    //: look before you leap check worthless.
    MyStruct** arr =(
        calloc(
            1 //:allocating 1 item: arr

            //:Amount of memory taken up by
            //:all 16 MyStruct pointers in array.
        ,   sizeof(MyStruct*)*num
        )
    );;

    //:Initialize only the EVEN slots:
    for(int i = 0; i < num; i+=2 ){
        //:Create new MyStruct in slot i,
        //:initialized with junk data.
        arr[i]= malloc(sizeof(MyStruct));
    };;

    //:If element not null, set it's whatever:
    for(int i = 0; i < num; i++){
        if(NULL != arr[i]){
            arr[i] -> whatever = i;
        };;
    };;

    //:Loop and print to confirm:
    for(int i = 0; i < num; i++){
        if(NULL != arr[i]){
            printf("whatever: %d\n", arr[i] -> whatever);
        };;
    };;

    //:ALTERNATIVELY:
    //:If we were going to use peoro's method,
    //:I would advise adding a ".exists" flag
    //:to your struct.

    typedef struct DoublePointersAreTooMuchWork{
        int exists;

        //:Because we are going to use malloc this
        //:time, we have no guarantee what this
        //:value will be. but you will probably
        //:see all of them == 0. If you set
        //: num=1000 you'll probably see a non-zero
        //: entry somewhere. But, no guarantees!
        int mystery_value;
    } MyStruct02;

    MyStruct02* arr2 = malloc(sizeof(MyStruct02)*num);
    for(int i = 0; i < num; i++ ){

        if( i%2 ){ //:evens
            arr2[i].exists = 1;
        }else{
            arr2[i].exists = 0;
        };;
    };;

    for(int i = 0; i < num; i++ ){
        if( arr2[i].exists ){
            printf("Exists:val:%d\n", arr2[i].mystery_value);
        }else{
            printf("[Pretend_I_Dont_Exist]\n");
        };
    }

    printf("[END:main]\n");
} //[[main]____________________________________]//

/** ****************************************** ***
OUTPUT:
[BEG:main]
whatever: 0
whatever: 2
whatever: 4
whatever: 6
whatever: 8
whatever: 10
whatever: 12
whatever: 14
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[END:main]
*** ****************************************** **/

While I am at it. If you want to run from the command line, name the file: "NAE.C99", then create a bash file called "NAE.SH" and put this into it. Double click the script to run it, or use "./NAE.SH" where it resides in your git bash terminal.

##################################################
############################# SC[ hkmf-strict ] ##
##################################################
base_name_no_extension="NAE"
##################################################
MY_COMMAND_STRING=$(cat << GCC_COMMAND_01
    gcc                                     
    -x c                                    
    -c $base_name_no_extension.C99          
    -o my_object_file.o                     
    -m64                                    
GCC_COMMAND_01
)                                       
C=$MY_COMMAND_STRING  ############################
C=$C"-Werror        " ## WarningsAreErrors      ##
C=$C"-Wfatal-errors " ## StopAtFirstError       ##
C=$C"-Wpedantic     " ## UseStrictISO_C         ##
C=$C"-Wall          " ## WarnAboutAnyWeirdCode  ##
C=$C"-Wextra        " ## "-Wall" WarningsExtra  ##
C=$C"-std=c99       " ## VersionOf_C_ToUse      ##
MY_COMMAND_STRING=$C  ############################

echo $MY_COMMAND_STRING
     $MY_COMMAND_STRING

C1=" gcc -o EXE.exe my_object_file.o "    
C2=" ./EXE.exe                       "    
C3=" rm my_object_file.o             "    
C4=" rm EXE.exe                      "  
$C1 && echo "OK:"$C1 || "FAIL:$C1"
$C2 && echo "OK:"$C2 || "FAIL:$C2"
$C3 && echo "OK:"$C3 || "FAIL:$C3"
$C4 && echo "OK:"$C4 || "FAIL:$C4"
##################################################
read -p "[END_OF_BUILD_SCRIPT:PressAnyKey]:"
##################################################
############################# SC[ hkmf-strict ] ##
##################################################

This is C99 code by the way. I try to write it avoiding any C99 specific features though.

Comments

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.