14

我有这个 C 代码:

#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;
}

它有一个结构和一个初始化该结构的函数。如果该函数出现故障,我要做的是返回 NULL 。

gcc 错误信息:

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

看起来返回NULL而不是结构是无效的,那么在这种情况下如何表达结构初始化失败(没有结构指针)?

4

4 回答 4

17
 if( mystruct == NULL )

mystruct不是指针,因此您无法将其与NULL.

你有三个选择:

  1. 添加一个状态字段来MyStruct指示结构是否已正确初始化。
  2. 在堆上分配结构并通过指针返回。
  3. 将结构作为指针参数传递并返回状态码(感谢@Potatoswatter)。
于 2012-05-18T11:17:32.720 回答
4

结构不是指针。如果您希望能够返回 NULL,则必须在堆上分配结构,以便可以返回指向它的指针,然后让调用者清理。

这样,您可以指示失败,例如:

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;
}
于 2012-05-18T11:20:30.053 回答
2

NULL如果函数返回指针,则可以使用。在这种情况下,您返回一个对象,这意味着您必须返回一个真实的、现有的对象。

这样做的一种方法是在结构中有一个“ok”字段,您可以在 init 函数中设置该字段,并且您可以签入调用者。

另一种方法是重写代码,以便动态分配结构并返回指针,这样你可以在失败时返回 NULL。(但请注意,动态分配事物还有其他缺点。)

于 2012-05-18T11:19:59.690 回答
0

正如 Als 指出的那样, mystruct 不是指针,因此比较并不意味着有意义。

您必须执行以下任一操作:

a)动态分配结构并在成功时返回。否则释放它并返回 null

或者

b) 在结构中包含一个错误标志并对其进行测试。

于 2012-05-18T11:19:07.693 回答