简体   繁体   中英

C: Initializing a struct and assigning it to pointer in function parameter

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.

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.

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);
    }
}

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM