osm
osm

Reputation: 622

Value of Passed-By-Value Struct Does Not Change

I am trying to understand how to pass a struct by reference in order to create a linked list. The method I am using is similar to the example code given below. However, when this code is run, the *tester declared in the main function always stays as NULL. Is the passing of a struct to the addNode() function in this way inappropriate (the compiler does not raise any warnings)?

struct test{
  int num;
  struct test *next;
};
void addNode (int num, struct test* tester);

int main (void){
  struct test *tester = null;
  addNode(1, tester);
}

void addNode(int num, struct test* tester){
  struct test *example = malloc(sizeof(struct test));
  example->num = num;
  if (tester == NULL){
    tester = example;
  } else{
    tester->next = example;
  }
}

Upvotes: 1

Views: 334

Answers (3)

Ed Swangren
Ed Swangren

Reputation: 124682

First off, you're assigning NULL to your input. This:

if (tester = NULL)

should be

if (tester == NULL)

Secondly, in that same branch, you assign a new value to tester. However, everything in C is passed by value (copy), so your function receives a copy of a pointer. Therefore, you are only mutating the function's local copy. You need another level of indirection:

#include <assert.h>

struct test{
  int num;
  struct test *next;
};

void addNode (int num, struct test* tester);

int main (void){
  struct test *tester = NULL;
  addNode(1, &tester);
}

void addNode(int num, struct test** tester){
  / * wrong, check next item */
  assert(tester != NULL);

  struct test example = malloc(sizeof(struct test));
  example->num = num;
  if (*tester == NULL){
    *tester = example;
  } else{
    (*tester)->next = example;
  }
}

Last, malloc returns a void*, which can implicitly be converted to any other type of pointer. It does not however return an "instance". So this is wrong:

struct test example = malloc(sizeof(struct test));

and should be:

struct test *example = malloc(sizeof *example);

Upvotes: 1

haccks
haccks

Reputation: 106022

In addNode function the pointer tester no longer points to the location pointed by the tester in main. function and change your function to

void addNode(int num, struct test** tester){
    struct test *example = malloc(sizeof(struct test));
    if (NULL == example )
         exit(0);        // Not enough memory

    example->num = num;  
    if (NULL == *tester)
         *tester = example; 
    else
        (*tester)->next = example;
}  

Call this function from main as addNode(1, &tester);. Now *tester is an alias for tester in main.

Upvotes: 2

Theodoros Chatzigiannakis
Theodoros Chatzigiannakis

Reputation: 29213

You are saving the pointer returned by malloc as a struct:

struct test example = malloc(sizeof(struct test));

Perhaps you wanted to store it as a pointer to struct, so that example and tester have matching types:

struct test* example = malloc(sizeof(struct test));

Then, this will make sense:

tester = example;

Upvotes: 1

Related Questions