0

I'm trying to allocate the char** path array in my batiment struct

#ifndef SDL2_BATIMENTS_H
#define SDL2_BATIMENTS_H

typedef struct{
    int x;
    int y;
}vecteur;

typedef struct{
    int numtype;        //Détermine quelle representation du batiment (route nor/ route sud...)
    char** tabpath;     // tableau de chemin d'acces aux images
    vecteur size;       // Taille du batiment en (x,y)
    int habitant;

}batiment;

typedef struct {
    vecteur** tuile;
    batiment* tabbatiment; //tableau de batiment
}Monde;

Monde* InitBatiment(Monde* monde);
vecteur toGrid(float x,float y);




#endif //SDL2_BATIMENTS_H

I've tried to allocate it like an array[][], at first it seems to be working with no error but everytime i try to access it my program crashes

for(int i=0; i<14;i++)
{
    monde->tabbatiment[i].tabpath = malloc(7 * sizeof (char*));

        for (int y = 0; y < 7; y++)
            monde->tabbatiment[i].tabpath[i] = (char*)malloc(50 * sizeof(char));

}

Ok First of all thank you for your answer, I changed my code to this but everytime my program try to call strcpy it crashes. I think I still have an allocation problem or a memory leak.

    for(int i=0; i<14;i++)
    {
            monde->tabbatiment[i].tabpath = calloc(10,sizeof(char*));

        for(int y = 0; y < 10; y++)
            monde->tabbatiment[i].tabpath[i] = calloc(30 ,sizeof(char));

    }


    FILE *f;
    char c;
    int numbatiment;
    f=fopen("batiment.txt","r");

    int x,y,numbat,numtype;
    const char path[50];



    for(int i =0;i<16;i++)
    {
        fscanf(f,"%d %d %d %d %s ",&numbat,&x,&y,&numtype,&path);

        printf("%s",path);

        strcpy(monde->tabbatiment[numbat].tabpath[numtype],path);
        monde->tabbatiment[numbat].size.x = x ;
        monde->tabbatiment[numbat].size.y=y ;
        monde->tabbatiment[numbat].numtype = numtype;
        printf("%d %d %d %d %s\n",numbat,monde->tabbatiment[numbat].size.x,monde->tabbatiment[numbat].size.y,monde->tabbatiment[numbat].numtype,monde->tabbatiment[numbat].tabpath[numtype]);


    }
    fclose(f);
  • 1
    Your first loop (why is there a loop in the first place?) first allocates an array of size 34, then your second tries to access up to index 44 - how did you expect that to work? – UnholySheep Nov 02 '22 at 12:58
  • You're using magic numbers like 45, 7, 15, 35,... that's a very bad idea. – Jabberwocky Nov 02 '22 at 13:12
  • `for(int i=0; i<14;i++)` --> `for(int i=0; i<15;i++)` – Support Ukraine Nov 02 '22 at 13:18
  • 2
    Why did you you put the "monde->tuile" stuff in the middle of the code doing the "monde->tabbatiment" stuff. Very confusing... – Support Ukraine Nov 02 '22 at 13:20
  • 3
    You assign to `monde->tuile` 35 times... So you keep overwriting the value causing a good portion of memory leaks... should the whole loop simply be replaced by `monde->tuile = malloc(45 * sizeof(vecteur*));` – Support Ukraine Nov 02 '22 at 13:22
  • OT: Avoid writing code using your native language for variables, comments, etc... Sooner or later you'll have to share the code with someone that doesn't understand your language. Maybe you would post the code on SO... – Support Ukraine Nov 02 '22 at 13:24
  • 1
    The second for-loop is really interresting... `monde->tuile[0]` will get 0 vecteur. `monde->tuile[1]` will get 1 vecteur. `monde->tuile[2]` will get 2 vecteur. Interresting... but is that really what you want? – Support Ukraine Nov 02 '22 at 13:27

1 Answers1

0

Could you elaborate what you are exactly trying to accomplish with the code? It feels like there is more to it then a simple bug, but more of an implementation issue as a whole.

I cannot replicate your SEGFAULT for what it's worth. I do run into a lot of memory issues in valgrind, all of which could be attributed that you allocate memory in a loop, where you could've easily done it in a linear block (hence why I'm afraid that there might be more to this).

To directly answer your question: allocating memory for a string can go 2 ways: either you allocate enough memory from the start for which you are certain the any string you throw at it will be smaller than the allocated memory. Or you allocate memory on the go based on the length of the string that you are adding to your array.

In both cases you would be looking at a combination of malloc/calloc and strcpy/strncpy (the latter in both having my preference most often). Allocate memory where the string should reside, than copy a local buffered value to the designated memory address.

Anyway, I've refactored your example to this. I have to say: take a GOOD look at how you are using indexes in loops. You are going out of bounds often, which might trigger a SEGFAULT. For monde->tuile for instance you allocate 35 slots, but the next thing you do is loop the tuile index to 44. I've also included some define statements which are good practice over magic numbers.

#define SIZE_BATIMENT   15
#define SIZE_TUILE      34
#define SIZE_TABPATH    8
#define MAX_STRING_LEN  64

Monde *monde = calloc(1, sizeof monde);

monde->tuile = calloc(SIZE_TUILE, sizeof(vecteur *));
for (int i=0 ; i <= SIZE_TUILE ; i++)
{
    monde->tuile[i] = (vecteur*)malloc(45 * sizeof(vecteur));
}

// Assign memory to allow MAX_STRING_LEN sizes
monde->tabbatiment  = calloc(SIZE_BATIMENT, sizeof(batiment));
for(int i = 0; i <= SIZE_BATIMENT; i++)
{
    monde->tabbatiment[i].tabpath = calloc(SIZE_TABPATH, sizeof(char *));
    for (int j = 0; j <= SIZE_TABPATH; j++)
    {
        monde->tabbatiment[i].tabpath[j] = calloc(MAX_STRING_LEN, sizeof(char));
    }
}
Evert_B
  • 193
  • 5