在函数中初始化指针

Initializing a pointer in a function

示例结构:

struct MyList {
    struct myElem *head;
};

我是指针的新手。我已经得到了一些东西,但不是下面的东西。

这两个选项有什么区别?

struct MyList *newEmptyList() {
    struct MyList list;
    list.head = NULL;
    return &list;
}
struct MyList *newEmptyList() {
    struct MyList *list;
    list->head = NULL;
    return list;
}

两者都导致 undefined-behaviour:

struct MyList *newEmptyList() {
    struct MyList list;
    list.head = NULL;
    return &list;
}
struct MyList *newEmptyList() {
    struct MyList *list;
    list->head = NULL;
    return list;
}

在第一个中,您要返回堆栈上局部变量的地址。当函数 returns、 访问 之前在该堆栈上的值是未定义的行为。在您取消引用返回的指针之前,它不会导致未定义的行为。

第二个:

  1. 未分配到内存地址的指针使用起来很危险。导致未定义的行为
  2. list->head 取消引用 list 这会立即导致未定义的行为,因为指针没有指向可用的内存地址,而您正在尝试写入该内存地址...

正确的做法是:

struct MyList *newEmptyList() {
    struct MyList *list = malloc(sizeof(struct MyList));
    list->head = NULL;
    return list;
}

malloc()在堆上分配内存,returns分配内存开始的内存地址。

指针

C 中的指针基本上是保存其他变量地址的变量。

都错了:

这里你return指向一个局部变量的指针,但是一旦函数newEmptyList终止,list就不再存在了:

struct MyList *newEmptyList() {
    struct MyList list;
    list.head = NULL;
    return &list;
}

这是错误的,因为 list(这是一个指针)指向任何地方,因此您不能像这里一样取消引用它:list->head = NULL;

struct MyList *newEmptyList() {
    struct MyList *list;
    list->head = NULL;
    return list;
}

你可能想要这个:

struct MyList *newEmptyList() {
    struct MyList *list = malloc(sizeof(*list));
    list->head = NULL;
    return list;
}

malloc 为您的 list 指针分配内存。在调用 malloc 之后,list 指向一些有效内存。