AdamJames
AdamJames

Reputation: 367

Array inside struct filled with garbage after initialization

I defined a data structure (Foo) that contains an array of 25 pointers (members) to itself. I want to initialize each of those pointers to NULL, but my init function isn't working correctly. When my Foo f returns from foo_init(), only some of the members are NULL, others are just populated with random values.

//in Foo.h
#include <stdio.h>
#include <stdlib.h>

typedef struct Foo {
    struct Foo * members[25] ;
} Foo ;

void foo_init(Foo * f) ;

//in Foo.c
void foo_init(Foo * f) {
    f = (Foo*)malloc(sizeof(Foo));

    for (size_t i = 0 ; i < 25 ; i++) {
        f->members[i] = NULL ;
    }
    /* Ok here, all members are NULL */
}

//in main.c
#include "Foo.h"

int main(int argc, const char * argv[])
{

    Foo f ;
    foo_init(&f) ;

    /* why isn't every index of f.members NULL? */


    /* ... */
    return 0;
}

I ran my code through LLDB. Inside foo_init(), all members are NULL. But after returning from foo_init(), f.members is full of random garbage values.

Upvotes: 0

Views: 669

Answers (3)

Serve Laurijssen
Serve Laurijssen

Reputation: 9733

another option is to use a pointer to pointer if you want to allocate Foo inside foo_init(). This way f points to valid memory after returning from foo_init

void foo_init(Foo ** f) {
    *f = (Foo*)malloc(sizeof(Foo));

    for (size_t i = 0 ; i < 25 ; i++) {
        (*f)->members[i] = NULL ;
    }
}

int main()
{
    Foo *f;

    foo_init(&f);

    return 0;
}

Upvotes: 1

diapir
diapir

Reputation: 3040

The address of the Foo in your main is immediately overwritten by the call to malloc. Just remove that line and your initialization should work.

If you really want foo_init to allocate memory you can convert it to :

void foo_init(Foo **out_f) {
    Foo *f = malloc(sizeof *f);

    for (size_t i = 0 ; i < 25 ; i++) {
        f->members[i] = NULL;
    }

    *out_f = f;
}

Or simply return a pointer as it is idiomatic in C :

Foo *foo_init(void);

Upvotes: 5

Orelsanpls
Orelsanpls

Reputation: 23515

Try this then

Foo *f ;
foo_init(&f) ;


void foo_init(Foo ** f) {
    *f = (Foo*)malloc(sizeof(Foo));

    for (size_t i = 0 ; i < 25 ; i++) {
        (*f)->members[i] = NULL ;
    }
}

@TripeHound is right

Upvotes: 2

Related Questions