0

Because of an assignment at Uni, I face the weird problem of having to initialize a struct to a pointer provided as a function parameter. Everything appears fine inside of that init function, but once I try to access the objects's values inside a different function, they just appear to be empty.

As I'm horrible at explaining things, I got a small example with actual and expected output:

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

struct foo {
    int bar;
};

void init_foo(struct foo* f) {
    f = malloc(sizeof(struct foo));
    f->bar = 5;
    printf("bar0: %d\n", f->bar);
}

void print_foo(struct foo* f) {
    printf("bar1: %d\n", f->bar);
}

int main() {
    struct foo f;
    init_foo(&f);
    print_foo(&f);
}

Acutal output:

bar0: 5
bar1: 0

Expected output:

bar0: 5
bar1: 5

I haven't dealt with C all that much before, so if someone could provide an explanation and/or a solution to this, I'd be very thankful.

4 Answers 4

3

You need to get rid of the malloc(), it doesn't belong since main() already allocated memory for its local f variable. init_foo() just needs to populate the existing memory. By calling malloc(), you are changing the foo* pointer inside of init_foo() to point at different memory, ignoring the original memory that was passed in.

Try this instead:

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

struct foo {
    int bar;
};

void init_foo(struct foo* f) {
    f->bar = 5;
    printf("bar0: %d\n", f->bar);
}

void print_foo(struct foo* f) {
    printf("bar1: %d\n", f->bar);
}

int main() {
    struct foo f;
    init_foo(&f);
    print_foo(&f);
}

On the other hand, if you want init_foo() to allocate memory for the struct, then do this instead:

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

struct foo {
    int bar;
};

void init_foo(struct foo** f) {
    *f = malloc(sizeof(struct foo));
    if (f) {
        (*f)->bar = 5;
        printf("bar0: %d\n", (*f)->bar);
    }
}

void free_foo(struct foo* f) {
    free(f);
}

void print_foo(struct foo* f) {
    printf("bar1: %d\n", f->bar);
}

int main() {
    struct foo *f;
    init_foo(&f);
    if (f) {
        print_foo(f);
        free_foo(f);
    }
}

Or this:

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

struct foo {
    int bar;
};

struct foo* init_foo() {
    struct foo *f = malloc(sizeof(struct foo));
    if (f) {
        f->bar = 5;
        printf("bar0: %d\n", f->bar);
    }
    return f;
}

void free_foo(struct foo* f) {
    free(f);
}

void print_foo(struct foo* f) {
    printf("bar1: %d\n", f->bar);
}

int main() {
    struct foo *f = init_foo(&f);
    if (f) {
        print_foo(f);
        free_foo(f);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the additional knowledge, but just removing the malloc was sufficient in my case :)
2

In main(), f is an allocated version of the foo struct. You passed a pointer to that allocated structure to init_foo().

There is no need for f to be malloc()'ed inside of init_foo(). f already points to an allocated structure.

I think if you just remove the malloc(), it should work.

5 Comments

Thank you very much :) (You were the first one to answer this, so I'll accept as soon as I can)
"You were the first one to answer this" - only by 7 seconds ;-)
@RemyLebeau Gotta support the newcomers :P
Ha. Thanks. I've been writing "C" for way too long. I think my favorite language is PHP these days.
@HenryF I should have accepted the other answer then. What a monster would favor PHP over anything?!
2

Don't malloc inside init_foo; space was already allocated by the caller. So you're filling up the space you malloced, but not the space pointed to by the pointer passed to the function.

Comments

1

You are eclipsing struct foo* f.

You have a stack based structure struct foo f defined in main. You pass a pointer to it, to the init_foo function. However you then immediately replace that structure pointer with an allocated structure, and proceed to fill that structure in. The original struct foo* f which was passed into the init_foo function was therefore not modified.

You then leak the memory by exiting the init_foo function and then you print the uninitilized structure.

You do not need the memory allocation, remove it all. Simply initialize directly into the struct foo* f you pass into the init_foo function.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.