How to NULL a pointer (to a struct) from within a

2019-06-14 15:28发布

问题:

One Liner Question:
Can someone please explain why thisNode=NULL doesn't work in a function and how I can achieve the same result in some other way.

Introduction:
I have started using pointers to structs a lot recently as I have started studying Data Structures.

History:
I have coded stacks, queues, binary search trees and expression trees and will start coding an avl tree soon. Being a student I still am unaware of many concepts and would appreciate any help.

Methodology:
I always find other ways to achieve my required result (nulling the head node), like nulling it in the main function, or end up not nulling it at all and keeping it as a head/root node with null data and then adding other (useful) nodes to it. (Only use it as a head or pointer to the structure)

Confusion:
I do not understand why nulling a pointer to struct from within a function doesn't work but other things such as changing the structs data member's values work with no problems.

For Example:

thisNode->nextNode->data = thisNode->data; *//this does works*
thisNode = NULL; *//this doesn't work*


Image:

Question:
Can someone please explain why thisNode=NULL doesn't work in a function and how I can achieve the same result in some other way.

Problem Area:

void stackPop(stackNode *headNode){
    if (headNode!=NULL){
        if (headNode->nextNode!=NULL){
            stackNode *tempNode = getLatestStackNode(headNode);
            tempNode->prevNode->nextNode=NULL;
            tempNode->prevNode==NULL;
            tempNode->data=='.';
            tempNode=NULL;
            free(tempNode);
        }else if (headNode->nextNode==NULL){
            headNode->data='\0';
            headNode = NULL;
            free(headNode);
        }
    }else{
        printf("\nstack currently has no nodes\n");
    }
}

Entire Stack Code:

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


typedef struct stackNode{
    char data;
    struct stackNode *nextNode;
    struct stackNode *prevNode;
}stackNode;

stackNode* createStackNode(char value){
    stackNode *newStackNode = (stackNode*) malloc(sizeof(stackNode));
    newStackNode->nextNode=NULL;
    newStackNode->prevNode=NULL;
    newStackNode->data=value;
    return newStackNode;
}

stackNode* getLatestStackNode(stackNode *headNode){
    stackNode *tempNode = headNode;
    while (tempNode->nextNode!=NULL){
        tempNode=tempNode->nextNode;
    }
    return tempNode;
}

stackNode* stackPush(stackNode *headNode, char value){
    if (headNode==NULL){
        return createStackNode(value);
    } else {
        stackNode *tempNode = getLatestStackNode(headNode);
        tempNode->nextNode = createStackNode(value);
        tempNode->nextNode->prevNode=tempNode;
        return tempNode->nextNode;
    }
}

void stackPop(stackNode *headNode){
    if (headNode!=NULL){
        if (headNode->nextNode!=NULL){
            stackNode *tempNode = getLatestStackNode(headNode);
            tempNode->prevNode->nextNode=NULL;
            tempNode->prevNode==NULL;
            tempNode->data=='.';
            tempNode=NULL;
            free(tempNode);
        }else if (headNode->nextNode==NULL){
            headNode->data='\0';
            headNode = NULL;
            free(headNode);
        }
    }else{
        printf("\nstack currently has no nodes\n");
    }
}

char stackPeek(stackNode *headNode){
    stackNode *tempNode = getLatestStackNode(headNode);
    return tempNode->data;
}

void stackPeekPrint(stackNode *headNode){
    stackNode *tempNode = getLatestStackNode(headNode);
    printf("\n%c\n",tempNode->data);
}

void isNULL(stackNode *headNode){

    if (headNode==NULL){
        printf("\nIt is NULL\n");
    } else if (headNode!=NULL) {
        printf("\nIt isn't NULL\n");
    }
}

int main(){

    stackNode *x = stackPush(NULL,'x');
    stackPush(x,'u');
    stackPush(x,'w');

    stackPop(x);
    stackPop(x);
    stackPop(x);

    stackPeekPrint(x);
    isNULL(x);

}

回答1:

In C, all parameters are passed by value. In stackPop, headNode is passed as a parameter, so any changes to it are not reflected in the calling function.

You need to pass in the address of x from main so that it can be modified.

So change stackPop to this:

void stackPop(stackNode **headNode){     //  takes a pointer-topointer
    if (*headNode!=NULL){
        if ((*headNode)->nextNode!=NULL){
            stackNode *tempNode = getLatestStackNode(*headNode);
            tempNode->prevNode->nextNode=NULL;
            // no need to clear fields before freeing
            free(tempNode);
        }else if ((*headNode)->nextNode==NULL){
            // no need to clear fields before freeing
            free(*headNode);     // free first, then set to NULL
            *headNode = NULL;
        }
    }else{
        printf("\nstack currently has no nodes\n");
    }
}

And call it like this:

stackPop(&x);


回答2:

You are actually passing in headNode by value (i.e. a copy of the pointer is being passed in). You need to pass in a pointer to headNode