简体   繁体   中英

Passing C pointers by reference?

I found some entries for passing pointers by reference, but didn't really understand them.

I have written this function to insert a node in a linked list. It seems to work within the function, but the changes of the linkedList pointer do not affect the pointer back in the main function. Is there an easy fix? In the classroom example, the linkedList pointer is declared globally, but I thought it would be preferable to pass it around, so I could make more than one linked list.

void insert(node* linkedList, int value)
{
    node* newNode = malloc(sizeof(node));

    if (newNode == NULL)
    {
        // failed to make node
        printf("Failed to insert new node!\n");
        return;
    }

    newNode->n = value;

    printf("\n");
    printf("Before insert: \n");
    printf("\n");

    printf("linkedList ptr : %p\n", linkedList);
    printf("linkedList->n : %i\n", linkedList->n);
    printf("LinkedList->next : %p\n", linkedList->next);

    printf("\n");
    printf("newNode ptr : %p\n", newNode);
    printf("newNode->n : %i\n", newNode->n);
    printf("newNode->next : %p\n", newNode->next);

    newNode->next = linkedList;
    linkedList = newNode;

    printf("\n");
    printf("After insert: \n");
    printf("\n");

    printf("linkedList ptr : %p\n", linkedList);
    printf("linkedList->n : %i\n", linkedList->n);
    printf("LinkedList->next : %p\n", linkedList->next);

    printf("\n");
    printf("newNode ptr : %p\n", newNode);
    printf("newNode->n : %i\n", newNode->n);
    printf("newNode->next : %p\n", newNode->next);
}

I think an easy fix would be to change your function to return the new list head:

Node * insert( struct Node * list, int value )
{
    ...
}

Use like this:

myList = insert( myList, someNumber )


It's hard to explain the use case you want without pictures. You want to pass a pointer to your list head pointer to insert() . Inside insert() you can then modify what that pointer-pointer points to (dereference it) to alter your list head.

Declare your function like this:

void insert( struct Node ** ioList, int value ) { ... }

Here ioList is of type Node ** , which is a pointer to a pointer to a Node . (A rule of thumb: read types from right to left)

Call it like this:

struct Node * myList = /*create list here*/ ;
insert( &myList, /*some number*/ );

The & operator creates a pointer to it's argument. So we're getting a pointer to myList . (Which is a pointer to a Node )

Now we have a pointer that points to myList .

Inside insert , assign to *ioList to alter what ioList points to ( myList ):

// make myList point to the new list head:
*ioList = /*new list head*/

Pointers point to a location in memory. Your function creates a new memory location and assigns it to a pointer that has been passed by value. I assume you are trying to add a new node to your existing linked list.

Your function doesn't operate this way unfortunately as you are assigning a new address to your linked list every time.

I like the use of sparse arrays. If you know the max size of your list, they are easier to use than a contiguous location of memory that store structures that may have to be realloced later.

void insert(struct node* list[], int *currentIndex, int value)
{
    struct node * newNode;

     newNode = malloc(sizeof(node));
     list[*currentIndex++] = newNode;

     ....
}

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