2

my first time here. Tried to find a solution through searching, but i still cant see my problem here:

Struct

typedef struct
{
    float** image_data;  
    int m;             
     int n;             
} image;

shorted main

int main(int argc, char *argv[])
{
    int m, n, c, iters;
    image u;
    unsigned char *image_chars;
    char *input_jpeg_filename, *output_jpeg_filename;

    /*funtion importing jpeg sets chars and hight/width (works)*/ 
    import_JPEG_file(input_jpeg_filename, &image_chars, &m, &n, &c);

    allocate_image (&u, m, n);
    printf"m og n (in main function): %i %i\n", u->m, u->n);

    return 0;
}

allocating function

void allocate_image(image *u, int m, int n)
{
    u = malloc(sizeof(struct image));

    u->m=m;
    u->n=n;

    int i;
    u->image_data=(float**)malloc(m*sizeof(float*));
    for(i=0; i<m; i++){
        u->image_data[i]=(float*)malloc(n*sizeof(float));
    }

    printf("m og n: %i %i\n", u->m, u->n);
}

Should mention its a part of school assignment, but I was told there was no harm in asking rudimentary questions here. I'm also limited to C89.

So as an experienced coder may already see, it doesn't allocate properly. the m and n values are printed correctly inside the allocate function, but I'm not allowed to use u->m for some reason outside. I have a feeling I messed up some pointers vs. addresses, but I can't find it..

As for remaking all the code, I would like to try and keep the variables inside main (no globals).

nalzok
  • 14,965
  • 21
  • 72
  • 139
  • Welcome to Stack Overflow! [Please see this discussion on why not to cast the return value of `malloc()` and family in `C`.](http://stackoverflow.com/q/605845/2173917). – Sourav Ghosh Mar 31 '16 at 14:26
  • `u = malloc(sizeof(struct image));` only changes the function argument. It is not passed back to caller. – Weather Vane Mar 31 '16 at 14:28
  • 1
    outside the function - you should reference the members of 'image' like ... printf("m og n: %i %i\n", u.m, u.n); - as u is not a pointer to image. – Neil Mar 31 '16 at 14:31

2 Answers2

3

Presumably you can tell why this function doesn't work:

void negate(int x)
{
    x = -x;
}

It doesn't work because parameters in C are "passed by value". As a result, changes to formal parameter x can't affect the corresponding actual variable.

In your case,

void allocate_image(image *u, int m, int n)
{
    u = malloc(sizeof(struct image));
    ...

has the same problem. To modify a image in a function, you should pass a pointer to image; to modify a pointer to image in a function, you should pass a pointer to pointer to image.

Here is the refined allocating function:

void allocate_image(image **u, int m, int n)
{
    *u = malloc(sizeof (struct image));

    (*u)->m = m;
    (*u)->n = n;

    size_t i;
    (*u)->image_data = malloc(m * sizeof (float *));
    for(i = 0; i < m; i++){
        (*u)->image_data[i] = malloc(n * sizeof (float));
    }

    printf("m og n: %i %i\n", (*u)->m, (*u)->n);
}

Note that operator *(unary) has lower procedure than operator ->, so the parentheses cannot be omitted.

nalzok
  • 14,965
  • 21
  • 72
  • 139
0

The problem is, inside your function, you're trying to allocate memory for u whereas, you had passed the address of a statically-allocated variable. So, inside your function, you're writing into a temporary memory location, will will not be existing when you try to access back the passed argument in the caller.

Thereby, the memory instance of u inside the function is local to the function and the changes made will disappear when the function exits. Remove the memory allocation, you don't need that.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • to put in other words, either you have to return the pointer allocated for `u` or pass `u` with double indirection, `void allocate_image(image **u, int m, int n)`, then change all references of `u` to `*u` (location pointed by u). Of course you need to pass `&u` in your caller function. – ddz Mar 31 '16 at 14:44