0

I'm trying to use malloc on a struct called image. The function is:

void image_init(struct image* img, int w, int h) {
    img = malloc(sizeof(struct image));
    (*img).w = w;
    (*img).h = h;
}

And the function to free the image again is:

void image_destroy(struct image* img) {
    free(img);
}

But whenever I try to free the malloc-ed data I'm getting the error that the adress I'm trying to free was not malloc-ed before.

The struct of image is:

struct image {
    int w,h;
    int* data;
}

I call the functions with:

struct image img;
image_init(&img,100,100);
image_destroy(&img);
2
  • 1
    Did you check for what malloc() returns? Commented May 18, 2016 at 19:50
  • 3
    Let's save keystrokes with one-letter struct member names and then waste two characters on (*img).w instead of img->w! Brilliant. Commented May 18, 2016 at 20:16

4 Answers 4

5

First here

void image_init(struct image* img, int w, int h) {
    img = malloc(sizeof(struct image));
    (*img).w = w;
    (*img).h = h;
}

img is a copy of the original pointer passed to it, hence the code on first line inside function has no effect, since it makes the copy point somewhere - not the original object.

This:

struct image img;
image_init(&img,100,100);
image_destroy(&img);

doesn't make sense either (assuming you expected img to point somewhere after call to init). img isn't a pointer, how you expect it to point somewhere?


One way you could solve this could be

struct image *img = image_init(100,100);

where

struct image* image_init(int w, int h) {
    img = malloc(sizeof(struct image));
    (*img).data = NULL;
    (*img).w = w;
    (*img).h = h;
    return img;
}

Don't forget to call free on the pointer returned by above function - you will need to free data pointer separately too, in case you allocate it too.


NOTE: My best guess (if you also can't change prototype) is you want something like this:

void image_init(struct image* img, int w, int h) {
    img->data = malloc(sizeof(int) * w * h);
    img->w = w;
    img->h = h;
}

destroy:

void image_destroy(struct image* img) {
    free(img->data);
    free(img);
}

In main

struct image* img = malloc(sizeof(struct image));
image_init(img, 100, 100);
image_destroy(img);

PS. Or if you want the usage of those functions remain as you had in main go with the answer of Johnny Mopp.

Sign up to request clarification or add additional context in comments.

11 Comments

Thanks. But the calls of image_init and the prototype of it were given to us to implement so I thought we can't change it. Are there solutions that don't change it?
Or alternatively you can keep the structure similar to the original, but pass struct image **img as a parameter and assign *img with the malloced pointer.
@user3745172 In this case you don't need malloc. The function should be provided with an already allocated structure pointer. As you do in the question. Just remove the malloc line and you are done.
@user3745172 In that case you might need to use pointer to pointer. Refer to google please, check how to initialize a struct using pointer to pointer.
@user3745172 see update, if you can't change prototype
|
3

I think your assignment is not to allocate the img but the data ptr:

void image_init(struct image* img, int w, int h) {
    img->data = malloc(sizeof(int) * w * h);// Check for failure...
    img->w = w;
    img->h = h;
}
void image_destroy(struct image* img) {
    free(img->data);
}

1 Comment

This makes a perfect sense.
0
struct image img;
image_init(&img,100,100);
image_destroy(&img);

allocates an image struct on your stack. Why are you trying to malloc one? If you really want one on the heap then do

    struct image * image_init( int w, int h) {
        struct image *img = malloc(sizeof(struct image));
        img->w = w;
        img->h = h;
        return img;
    }
...  
    struct image *img = image_init(100,100);

Note the more idiomatic '->' use

if you want the one on the stack then do

void image_init(struct image* img, int w, int h) {
    img->w = w;
    img->h = h;
}

Comments

-4

You need to cast the malloc to struct because the return value of malloc is of type void.

1 Comment

Beware of applying rules enforced by C++ compilers to C code. They're different languages, and this is one place where there's a crucial difference.

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.