Sebastian Luke
Sebastian Luke

Reputation: 395

Allocating memory for a structure array inside another structure

I really don't know what the issue is here. The compiler says it's all okay, but when I run it, the executable crashes ( I believe it's a segmentation fault problem ). They say two minds are always better than one, so I hope you guys can find whatever I have missed.

Okay, so it goes this way: I have 2 structures:

struct _Color {

    unsigned char r,g,b;
    char *pchars;
}; //typedef to Color in header file

struct _XPM {

    unsigned int width;
    unsigned int height;
    unsigned char cpp; 
    unsigned int ncolors;
    Color *colta; //collor table
    unsigned int *data[];

}; //typedef to XPM in header file

Then, in a function I allocate memory for the XPM structure and then for the Color array inside the XPM structure (I won't write the fail safe code here):

XPM *imagine; //received as a parameter
imagine = ( XPM* ) malloc ( sizeof ( XPM ) + sizeof ( unsigned int* ) * width );
imagine -> colta = malloc ( ncolors * sizeof ( imagine -> colta ) ); 
/*I tried with both *imagine ->colta and imagine -> colta just to be safe */

The problem shows when I try accessing the fields in the Color table

imagine -> colta [ index ].r = r;

Maybe it's just a small mistake I made, but I cannot find it. Does anyone have an idea?

Thank you! :)

EDIT

The code in the main function to this extent is this:

XPM *img;
initXPM(img, 10, 10, 1, 3);
setXPMColor(img, 0, 255, 255, 255, "0");

The setXPMColor function goes like this:

void setXPMColor(XPM *imagine,
    unsigned int index,
    unsigned char r,
    unsigned char g,
    unsigned char b,
    char *charpattern) {


   imagine -> colta [ index ].r = r;
   imagine -> colta [ index ].g = g;
   imagine -> colta [ index ].b = b;
   imagine -> colta [ index ].pchars = charpattern;
}

Upvotes: 0

Views: 100

Answers (2)

BLUEPIXY
BLUEPIXY

Reputation: 40155

void func(type *pointer){
    //"type *pointer" : The only variable on the stack
    pointer = malloc(sizeof(type));//But is not set to the original.
    retrurn;
}

short test code :

#include <stdio.h>
#include <stdlib.h>

void init_int_pointer(int *p){
    p = malloc(sizeof(*p));
}

int main(){
    int *p = NULL;
    printf("before : %p\n", (void*)p);//NULL
    init_int_pointer(p);
    printf("after : %p\n", (void*)p);//NULL

    return 0;
}

to fix

1)
type * func(){
    type *pointer = malloc(sizeof(type));
    retrurn pointer;
}
...
type *p = func();

2)
void func(type **pointer){
    *pointer = malloc(sizeof(type));
    retrurn ;
}
...
type *p;
func(&p);

Upvotes: 0

unwind
unwind

Reputation: 400159

Your sizeof usage is wrong, sizeof ( imagine -> colta ) is the size of the pointer.

You mean:

imagine->colta = malloc(ncolors * sizeof *imagine->colta);
                                         ^
                                         |
                                    important!

Note the asterisk, which makes it mean "the size of the data pointed at by this pointer", i.e. sizeof (Color).

Also, make sure the allocations actually succeed, of course.

Also, please don't cast the return value of malloc() in C.

UPDATE:

Your problem seems to be in how you call the function that initializes the structures; you're dropping the top-level malloc()ed XPM pointer:

XPM *img;
initXPM(img, 10, 10, 1, 3);
setXPMColor(img, 0, 255, 255, 255, "0");

it should be something like:

XPM *img = initXPM(10, 10, 1, 3);
setXPMColor(img, 0, 255, 255, 255, "0");

And of course initXPM should return the local imagine variable, so that the caller gets that pointer.

Upvotes: 2

Related Questions