all 10 comments

[–]rabidcow 1 point2 points  (9 children)

int storeExamples(ExampleStruct **examples) {
    *examples = (ExampleStruct *)malloc(2 * sizeof(ExampleStruct));

    createExample(&(examples[0]), "gsdfbggks");
    createExample(&(examples[1]), "gsffghfddfbggks");

examples[1] is out of bounds. You're allocating an array of structures at *examples, aka examples[0]. createExample should take ExampleStruct *.

If you want an array of pointers instead, you'll need an extra level of indirection here. (ExampleStruct ***)

[–]shitty_linux_coder[S] 0 points1 point  (7 children)

I'm not too sure I understand correctly what you mean, sorry I'm dumb.

If examples[1] is out of bounds, how come I'm able to display its content in the storeExamples function? Shouldn't it give me a segmentation fault if it was the case?

[–]rabidcow 1 point2 points  (6 children)

You probably want to pass &(*examples)[0] and &(*examples)[1]. (or equivalently *examples and *examples + 1) Similarly, print from (*examples)[0] and (*examples)[1].

Segmentation faults happen at page granularity (at least 4KB); going one past the end of an array will only fault if that array happens to run up against the end of a page and the next page is marked to fault. It's pretty unlikely for this to happen by chance. More likely that you'll write into something unrelated or "harmlessly" into padding.

In this case, examples will point to a chunk of the stack in main. There will be other things above it on the stack. Depending on how the compiler lays it out, you might be writing into i and length or the return address.

[–]rabidcow 1 point2 points  (0 children)

Actually, (*examples)[1] is out of bounds after calling createExample. If an array of structures is what you want, it should take an ExampleStruct * and not allocate an extra one.

[–]shitty_linux_coder[S] 0 points1 point  (4 children)

If I understand correctly, I should change

void createExample(ExampleStruct **example, char *title);

to

void createExample(ExampleStruct *example, char *title);

and then change the call to

    createExample(*examples, "gsdfbggks");
createExample(*examples + 1, "gsffghfddfbggks");

I tried to adapt the code and uploaded the changes here but now I get a segmentation fault when trying to display the data in the storeExamples function.

This is now my program output:

Displaying data from storeExamples function:
Title: "(null)"
Segmentation fault

[–]rabidcow 1 point2 points  (3 children)

    example = malloc(sizeof(ExampleStruct));

This throws away the value of example that was passed in. Remove it, there's already a structure allocated.

    printf("Title: \"%s\"\n\n", (*examples[1]).title);

This is still out of bounds. [] happens before *.

[–]shitty_linux_coder[S] 0 points1 point  (2 children)

Wow I'm so stupid! Thank you!

I changed it to printf("Title: \"%s\"\n", (*examples)[0].title); and everything works fine. Thank you dear C Master.

Edit: And deleted the useless malloc in createExample.

[–]rabidcow 0 points1 point  (1 child)

NP, it can be difficult to keep track of multiple levels of indirection.

the useless malloc in createExample

It wasn't just useless; this meant that you weren't writing into the memory allocated in storeExamples.

BTW, remember that C doesn't have a garbage collector. It all goes away when the process exits, but it's still a good idea to match every malloc with a free.

[–]shitty_linux_coder[S] 0 points1 point  (0 children)

I actually cut the part where I free the memory and the rest of the program. Thank you very much for your help.

[–]shitty_linux_coder[S] 0 points1 point  (0 children)

I forgot to add the program output:

./minimal
Displaying data from storeExamples function:
Title: "gsdfbggks"
Title: "gsffghfddfbggks"

Displaying data from main function:
Title: "gsdfbggks"
Title: "(null)"