Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Segfault when I loop through the array of a dynamically allocated structure

Here’s the problem, I’m trying to allocate a struct containing an array of pixels but it gives me a segfault and I can’t find the error, here’s how I originally tried to do it:

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

typedef struct {
    int len;
    uint16_t tex_w;
    uint16_t tex_h;
    uint32_t** tex;
} Tex_Array;

int main(void)
{
    const uint8_t tex_num = 8;
    const uint16_t tex_w = 64;
    const uint16_t tex_h = 64;

    Tex_Array* wall_tex = malloc(sizeof(Tex_Array) + (tex_w * tex_h) * tex_num * sizeof(uint32_t));

    /* Texture generation */

    for(int x = 0; x < tex_w; x++) {
        for(int y = 0; y < tex_h; y++)
        {
            int xorcolor = (x * 256 / tex_w) ^ (y * 256 / tex_h);
            int ycolor = y * 256 / tex_h;
            int xycolor = y * 128 / tex_h + x * 128 / tex_w;
            wall_tex->tex[0][tex_w * y + x] = 65536 * 254 * (x != y && x != tex_w - y);
            wall_tex->tex[1][tex_w * y + x] = xycolor + 256 * xycolor + 65536 * xycolor;
            wall_tex->tex[2][tex_w * y + x] = 256 * xycolor + 65536 * xycolor;
            wall_tex->tex[3][tex_w * y + x] = xorcolor + 256 * xorcolor + 65536 * xorcolor;
            wall_tex->tex[4][tex_w * y + x] = 256 * xorcolor;
            wall_tex->tex[5][tex_w * y + x] = 65536 * 192 * (x % 16 && y % 16);
            wall_tex->tex[6][tex_w * y + x] = 65536 * ycolor;
            wall_tex->tex[7][tex_w * y + x] = 128 + 256 * 128 + 65536 * 128;
        }
    }

    /* Test if the program arrives here */

    printf("Generation is finished !\n");

    /* rest of initialization just for example */

    wall_tex->len = tex_num;
    wall_tex->tex_w = tex_w;
    wall_tex->tex_h = tex_h;

    return 0;

}

What I understand even less is that I tried to do it even more "literally" as below, with memcpy(), but it gives me exactly the same result (segfault) at copy time :

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

typedef struct {
    int len;
    uint16_t tex_w;
    uint16_t tex_h;
    uint32_t** tex;
} Tex_Array;

int main(void)
{
    const uint8_t tex_num = 8;
    const uint16_t tex_w = 64;
    const uint16_t tex_h = 64;

    uint32_t tex[8][tex_w * tex_h];

    /* Texture generation */

    for(int x = 0; x < tex_w; x++) {
        for(int y = 0; y < tex_h; y++)
        {
            int xorcolor = (x * 256 / tex_w) ^ (y * 256 / tex_h);
            int ycolor = y * 256 / tex_h;
            int xycolor = y * 128 / tex_h + x * 128 / tex_w;
            tex[0][tex_w * y + x] = 65536 * 254 * (x != y && x != tex_w - y);
            tex[1][tex_w * y + x] = xycolor + 256 * xycolor + 65536 * xycolor;
            tex[2][tex_w * y + x] = 256 * xycolor + 65536 * xycolor;
            tex[3][tex_w * y + x] = xorcolor + 256 * xorcolor + 65536 * xorcolor;
            tex[4][tex_w * y + x] = 256 * xorcolor;
            tex[5][tex_w * y + x] = 65536 * 192 * (x % 16 && y % 16);
            tex[6][tex_w * y + x] = 65536 * ycolor;
            tex[7][tex_w * y + x] = 128 + 256 * 128 + 65536 * 128;
        }
    }

    printf("Generation is finished !\n"); // It's okay'

    /* rest of initialization */

    Tex_Array* wall_tex = malloc(sizeof(Tex_Array) + sizeof(tex));

    wall_tex->len = tex_num;
    wall_tex->tex_w = tex_w;
    wall_tex->tex_h = tex_h;

    memcpy(wall_tex->tex, tex, sizeof(tex)); // Segfault here

    /* Test if the program arrives here */

    printf("Struct alloc is finished !\n");

    return 0;

}

Where am I going wrong with using malloc()?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I want to clarify that these are just shortened examples and I need to be able to allocate this structure in the real project.

>Solution :

Like I said in my comment, your allocation is only for the wall_tex pointer. Which you don’t really need to be a pointer or do to dynamic allocation:

Tex_Array wall_tex;  // Create one single Tex_Array structure object

Then you need to allocate the actual array for tex itself:

wall_tex.tex = malloc(sizeof *wall_tex.tex * tex_num);

And lastly create the sub-arrays:

for (unsigned i = 0; i < tex_num; ++i)
{
    wall_tex.tex[i] = malloc(sizeof *wall_tex.tex[0] * tex_w * tex_h);
}

If you need to dynamically allocate the Tex_Array structure object itself, then allocate only it:

Tex_Array *wall_tex = malloc(sizeof *wall_tex);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading