0

I'm trying to fill a structure field from a function to which the structure is given by pointer.

After allocating the structure with malloc the returned pointer is non null and the structure field is well initialized, however after returning to main. The pointer I passed to the function is null.

Here a simplified example

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

#define INFO(fmt, args...)      printf(fmt, ## args);
#define ERROR(fmt, args...)     printf("In %s : " fmt, __func__, ## args);

typedef enum 
{
    ERR_OK = 0,
    ERR_KO = -1,
    ERR_MALLOC_FAIL = -2,

}error_t;

typedef struct 
{
    unsigned int field;
}test_struct;

int struct_constructor(test_struct* myStruct, unsigned int field)
{
    myStruct = malloc(sizeof(test_struct));

    if(NULL == myStruct)
    {
        ERROR("Error allocating memory for myStruct\n");
        return ERR_MALLOC_FAIL;
    }

    INFO("passed field = %d\n", field);

    myStruct->field = field;

    INFO("struct field = %d\n", myStruct->field);

    return ERR_OK;
}

int main(void)
{
    test_struct* myStruct = NULL;

    struct_constructor(myStruct, 1);

    if(myStruct == NULL)
    {
        INFO("NULL structure in main\n");
    }
}

And here is the output :

passed field = 1
struct field = 1
NULL structure in main

I don't understand why the structure's pointer is not null inside the function and is null in main.
Also I don't want to return the pointer as I'm using return code to check what's going wrong in my functions.

Arkaik
  • 852
  • 2
  • 19
  • 39
  • 1
    You have to pass a pointer to the pointer to the function for the changes made in the function to affect the calling code. It’s a very common mistake in novice C code. It’s a duplicate many roomed over. – Jonathan Leffler Dec 27 '17 at 15:10

1 Answers1

3

Well because C is pass by value so any change you made is to the local pointer variable. main() has nothing to do with it. If you return that pointer and assign it to one you want to change it would work.

Or pass address of it and make changes to the original variable.

struct_constructor(&myStruct, 1);

And

int struct_constructor(test_struct** myStruct, unsigned int field)
{
    *myStruct = malloc(sizeof(test_struct));

    if(NULL == *myStruct)
    {
        ERROR("Error allocating memory for myStruct\n");
        return ERR_MALLOC_FAIL;
    }

    INFO("passed field = %d\n", field);

    myStruct->field = field;

    INFO("struct field = %d\n", (*myStruct)->field);

    return ERR_OK;
}
user2736738
  • 30,591
  • 5
  • 42
  • 56