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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.