如何使用函数将结构体指针设置为NULL

3

我刚开始接触C语言。 我像这样设置了一个链表:

#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

#define len(array) (sizeof(array) / sizeof(array[0]))

#define true 1
#define false 0

struct node{
    int data;
    struct node* next;
};

typedef struct node node;

node* initNode(void){
    node* headNode;
    headNode = (node *)malloc(sizeof(node));
    headNode -> next = NULL;
    return headNode;
}

node* create(int* array, int length){
    node* newNode;
    node* lastNode;
    node* headNode = initNode();
    newNode = (node *)malloc(sizeof(node));
    headNode -> data = array[0];
    int arrayLength = 1;
    int hasSetHead = false;
    while(arrayLength < length){
        if (! hasSetHead){
            lastNode = headNode;
            hasSetHead = true;
        }
        memset(newNode, 0, sizeof(node));
        newNode -> data = array[arrayLength];
        newNode -> next = NULL;
        lastNode -> next = newNode;
        lastNode = newNode;
        newNode = (node *)malloc(sizeof(node));
        if (newNode == NULL) exit(0);
        arrayLength++;
    }
    return headNode;
}

void clear(node* headNode){
    node* nextNode;
    if (headNode == NULL) return;
    while (headNode -> next != NULL){
        nextNode = headNode -> next;
        free(headNode);
        headNode = nextNode;
    }
    *headNode = NULL;
}

int main(void){
    int array[] = {1,2,3,4,5,6,7};
    int length = len(array);
    node* list = create(array, length);
    clear(list);
    system("pause");
    return true;
}

我希望通过使用clear(结构体指针)来清除我的结构体。但是在clear()的最后一行,我得到了这个错误:
error: incompatible types in assignment

我应该做什么呢?谢谢!请忘记我的糟糕英语。

谢谢!@Marievi 我已经像这样更改了代码:

headNode = NULL;

但是当我想要打印链表时,它似乎出现了问题。以下是我的代码:
void clear(node* headNode){
    node* nextNode;
    if (headNode == NULL) return;
    while (headNode -> next != NULL){
        nextNode = headNode -> next;
        free(headNode);
        headNode = nextNode;
    }
    *headNode = NULL;
}

当我调用这个函数时,似乎出现了内存泄漏。

1
永远不要将malloc的结果强制转换。请参见- https://dev59.com/dHRB5IYBdhLWcg3wgHWr - GAURANG VYAS
谢谢!我学会了。但似乎没有解决这个问题。 - 桂小方
那与你的问题有关,但这是应该遵循的一种实践。只需查看链接即可。 - GAURANG VYAS
4个回答

1

我们可以使用 free(headNode) 吗? - GAURANG VYAS
@GAURANGVYAS 当清空一个列表时,你应该释放所有你分配的元素。 - Marievi
@桂小方 这是一个关于编译你的代码的问题。如果你现在遇到了不同的问题,你可以编辑你的问题或者提出一个新的问题。 - Marievi
@Marievi 谢谢,我已经修改了问题。 - 桂小方
@Marievi 这个回答部分是错误的。请纠正或删除它。在 clear 结尾处的 headNode = NULL; 是一个 NOP。你可以直接将其删除。 - Jabberwocky
显示剩余2条评论

1
在你的函数中声明了一个名为headNode的变量。
node* headNode

"

"相当于"

"。
struct node *headNode

因为类型node的作用域内有typedef,所以出现了问题的赋值。
*headNode = NULL;

尝试将类型为void *的空指针常量NULL分配给由*headNode指定的对象,该对象是struct node。错误提示了你不能将指针值分配给结构类型的对象。您可以将NULL分配给headNode本身...
headNode = NULL;

正如另一个答案所观察到的那样,虽然编译器会接受这个,但它不会产生你想要的效果,因为headNode函数参数是函数局部变量。它的值始终是其参数(指针)值的副本,对本地副本的更改不会影响调用者的原始参数。
如果您希望更改调用者的副本,则有两个主要选择:
  1. 返回修改后的值(NULL),并让调用者将其分配给原始变量,如果愿意的话,或
  2. 而不是传递头指针本身,传递指向包含头指针的变量的指针(类型为node **)。
这两种替代方案都需要对调用者进行更改;后者还需要进一步更改函数实现。

通过您的分析,我理解了它的操作原理,非常感激! - 桂小方

1
这行代码(去掉 '*' 后)实际上什么也没做,因为它只改变了本地的 headNode 参数(并且 100% 会被编译器完全移除)。
 headNode = NULL;

如果你想将NULL分配给更高级别的指针,你需要将node **headnode传递给这个函数或将其变为node *:。
void clear(node** headNode){
    node* nextNode;
    if (*headNode == NULL) return;
    while (*headNode -> next != NULL){
        nextNode = *headNode -> next;
        free(*headNode);
        *headNode = nextNode;
    }
    *headNode = NULL;
}

和调用

 clear(&list);

或者更好
node *clear(node* headNode){
    node* nextNode;
    if (headNode == NULL) return;
    while (headNode -> next != NULL){
        nextNode = headNode -> next;
        free(headNode);
        headNode = nextNode;
    }
    return NULL;
}

and the call :

list = clear(list);

谢谢!我已经通过你的答案解决了这个问题! - 桂小方
第一个示例无法编译,而且这两个示例仍然没有释放链表的最后一个元素。 - Jabberwocky
@Michael Walz并没有询问他的算法,只是关于编程语言的问题。 - 0___________

0

clear函数过于复杂且有误。它不能释放最后一个元素。

以下是正确的:

void clear(node* headNode) {
  node* nextNode;

  while (headNode != NULL) {
    nextNode = headNode->next;
    free(headNode);
    headNode = nextNode;
  }
}

如果你想让 clear 函数将其参数设置为 NULL

你需要这样做:

void clear(node** headNode) {
  node* nextNode;

  while (*headNode != NULL) {
    nextNode = (*headNode)->next;
    free(*headNode);
    *headNode = nextNode;
  }

  *headNode = NULL;
}

然后像这样调用它

clear(&list);
// now list is NULL

谢谢,你的函数也帮了我很多~ - 桂小方

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接