简体   繁体   中英

Returning NULL if structure initialization failed in C?

I have this C code :

#include<stdio.h>

typedef struct {
    int foo;
} MyStruct;

MyStruct init_mystruct(void);

int main(void) {

    MyStruct mystruct   = init_mystruct();

    if( mystruct == NULL ) {
        /* error handler */
    }

    return(0);
}

MyStruct init_mystruct(void) {

    MyStruct mystruct;
    int is_ok   = 1;

    /*
     * do something ...
     */

    /* everything is OK */
    if( is_ok )
        return mystruct;
    /* something went wrong */
    else
        return NULL;
}

It has a structure and a function to initialize that structure. What I'm trying to do is to return NULL if there was a failure in that function.

The gcc error message :

code.c: In function ‘main’:
code.c:13: error: invalid operands to binary == (have ‘MyStruct’ and ‘void *’)
code.c: In function ‘init_mystruct’:
code.c:34: error: incompatible types when returning type ‘void *’ but ‘MyStruct’ was expected

It looks that returning NULL instead of a structure is not valid, so how do I express the failure of structures initialization in this case (no structure pointer)?

 if( mystruct == NULL )

mystruct is not a pointer, so you cannot compare it with NULL .

You have three options:

  1. Add a status field to MyStruct to indicate whether the struct has been initialized correctly.
  2. Allocate the struct on the heap and return it by pointer.
  3. Pass the structure as a pointer argument and return a status code (thanks @Potatoswatter).

A structure is not a pointer. If you want to be able to return NULL, you're going to have to allocate the structure on the heap so you can return a pointer to it, and let the caller clean up afterwards.

That way, you can indicate failure, something like:

MyStruct *init_mystruct (void) {
    MyStruct *mystruct = malloc (sizeof (*mystruct));
    if (mystruct != NULL)
        return NULL;

    int is_ok   = 1;
    /* do something ... */

    /* everything is OK */
    if( is_ok )
        return mystruct;

    /* something went wrong */

    free (mystruct);
    return NULL;
}

int main (void) {
    MyStruct *mystruct = init_mystruct();

    if (mystruct == NULL) {
        /* error handler */
        return -1;
    }

    free (mystruct);

    return 0;
}

NULL can be used if a function returns a pointer . In this case, you return an object, which means that you have to return a real, existing object.

One way of doing this is to have an "ok" field in the struct that you could set in the init function, and that you could check in the caller.

Another way is to rewrite your code so that you allocate a struct dynamically and return a pointer, that way you could return NULL on failure. (Note, however, that there are other drawbacks of allocating things dynamically.)

As Als pointed out, mystruct is not a pointer and therefore the comparison does not mean sense.

You have to do either:

a) Dynamically allocate the structure and return that on success. Otherwise free it and return null

or

b) Include in the structure an error flag and test that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM