C pointer array with elements of other pointer array

Viewed 44

I have 2x structs, one for color (PixelColor) and the second for holding an array of available colors (Palette).

typedef struct{
    int r;
    int g;
    int b;
    int a;
}PixelColor;

typedef struct{
    int size;
    PixelColor *palette;
}Palette;

One game's global palette and one for objects that reference colors in the global palette.

PixelColor ShovelKnightColors[] = {
    {0, 0, 0, 255}, 
    {44, 44, 44, 255}, 
    {96, 96, 96, 255}, 
    {200, 192, 192, 255}, 
    {0, 64, 88, 255}, 
    ...
};
Palette GamePalette = {59, ShovelKnightColors};
PixelColor CharacterColors[4];
//This doesn't work
CharacterColors[0] = GamePalette.palette[0];
CharacterColors[1] = GamePalette.palette[17];
CharacterColors[2] = GamePalette.palette[24];
CharacterColors[3] = GamePalette.palette[37];

Palette CharacterPalette = {4, CharactersColors};

I'm probably missing a fundamental thing, but I tried any idea I had. As an example:

PixelColor CharacterColors[] = {
    GamePalette.palette[0], 
    GamePalette.palette[17], 
    GamePalette.palette[24],
    GamePalette.palette[37]
}

All this is outside the main function, just to learn things I don't know about initiation. Please suggest a way to get closest to the initial idea of referencing the same values, because the goal is to create an ESP32 microcontroller project.

1 Answers

The problem with your code has to do with the fact that you have arrays inside your structs, and arrays need to be initialized.

My suggestion would be to create a FillPalette() function that would do the appropriate memory allocation each time:

void FillPalette(Palette *p, int size, PixelColor pixelColors[])
{
    p->size = size;
    p->palette = malloc( sizeof(PixelColor) * size );

    for(int i = 0; i < size; ++i)
    {
        p->palette[ i ].r = pixelColors[ i ].r; 
        p->palette[ i ].g = pixelColors[ i ].g;
        p->palette[ i ].b = pixelColors[ i ].b;
        p->palette[ i ].a = pixelColors[ i ].a;
    }
}

Another possibility, in order to avoid the for loop, is to use memcopy once the array has been initialized.

Anyway, remember to clear the palette when is not going to be used anymore:

void ClearPalette(Palette *p)
{
    p->size = 0;
    free( p->palette );
}
Related