0

I have Problems with accessing the 2D Array in a typedef from a other function over a pointer, even if i allocate the array in heap!

#include <stdlib.h>
#include <stdio.h>
typedef struct {
    int a;
    int b;
    int **data;
} Image;
Image *createImage(int a, int b) {
    Image createImage;
    createImage.data = malloc(a * sizeof(int *));
    for (int i = 0; i < a; i++) {
         createImage.data[i] = malloc(b * sizeof(int));
    }
    Image *imagePointer = malloc(sizeof(Image));
    imagePointer = &createImage;
    return imagePointer;
}
int main () {
     int a = 70;
     int b = 90;
     Image *imagePointer = createImage(a, b);
     for (int i = 0; i < a; i++) {
          for (int j = 0; j < b; j++) {
               imagePointer->data[i][j] = i + j;
          }
     }
}

I get an error at load Image because i have done something wrong with accessing the allocated storage. What should i change?

Jonathan

  • Edit the question to provide a [mre]. – Eric Postpischil Feb 12 '22 at 18:58
  • 1
    `imagePointer = &createImage;` doesn't do what you think it does. Also you need to check for malloc failing. – zwol Feb 12 '22 at 19:13
  • @zwol I think, that i am hand over the place in storage where createImage is stored to imagePointer to allocate it in heap! What else is it doing? – Jonathan Pi Feb 12 '22 at 19:36
  • You are leaking the heap allocation you just made and resetting the pointer to refer to a local variable that's about to go out of scope. – zwol Feb 12 '22 at 19:44

2 Answers2

0

Instead of returning a pointer to Image return the local variable itself and it works. Also variable name and function name should not be same createImage it creates confusion sometimes.

#include <stdlib.h>

typedef struct {
    int a;
    int b;
    int **data;
} Image;
Image createImage(int a, int b) {
    Image ci;
    ci.data = malloc(a * sizeof(int *));
    for (int i = 0; i < a; i++) {
         ci.data[i] = malloc(b * sizeof(int));
    }
    return ci;
}
int loadImage () {
     int a = 70;
     int b = 90;
     Image imagePointer = createImage(a, b);
     for (int i = 0; i < a; i++) {
          for (int j = 0; j < b; j++) {
               imagePointer.data[i][j] = i + j;
          }
     }
}

int main(int argc, char const *argv[])
{
    loadImage();
    return 0;
}
Darth-CodeX
  • 2,166
  • 1
  • 6
  • 23
0
  1. It is not 2D array only an array of pointers.
  2. Use size_t for sizes
  3. Use objects not types in sizeof
  4. Always check the result of malloc

I would use flexible array member and array pointers to remove one level of indirection and ease allocation and deallocation (only one malloc/free needed)

typedef struct {
    size_t a;
    size_t b;
    unsigned data[];
} Image;

Image *createImage(const size_t a, const size_t b) 
{
    Image *imagePointer;
    imagePointer = malloc(sizeof(*imagePointer) + a * b * sizeof(imagePointer -> data[0]));
    if(imagePointer)
    {
        imagePointer -> a = a;
        imagePointer -> b = b;
    }
    return imagePointer;
}


int main (void) 
{
     const size_t a = 70;
     const size_t b = 90;

     Image *imagePointer = createImage(a, b);
     if(imagePointer)
     {
        unsigned (*image)[imagePointer -> b] = (unsigned (*)[imagePointer -> b])imagePointer -> data;
        for (size_t i = 0; i < a; i++) 
        {
            for (size_t j = 0; j < b; j++) 
            {
                image[i][j] = i + j;
            }
        }
     }
}
0___________
  • 60,014
  • 4
  • 34
  • 74