Reputation: 89
Here is my code, I'm getting a segmentation fault and I don't know why...
I'm creating a grid which n
is its size, tab
is an array which his type is cellule : a cell has 2 values. So I'm creating in the function creer_grille
an array I malloc
it (size can be 4 6 or 8) and I initialize the cells values with -1 and 0. Then in the following function I'm testing the creer_grille
function.
typedef struct
{
int val;
int initial;
} cellule;
typedef struct
{
cellule *tab;
int n;
} grille;
grille *creer_grille(int n)
{
grille *g;
int i;
assert(n == 4 || n == 6 || n == 8 && "Taille de la grille différent de 4,6 ou 8");
g->n = n;
g = malloc(sizeof(int) * (n*n));
if (g->tab == NULL)
exit(-1);
for (i = 0; i < n*n; i++)
{
g->tab[i].val = -1;
g->tab[i].initial = 0;
}
return g;
}
void detruire_grille(grille * g)
{
free(g);
}
void test_creer_grille(){
int i,k;
for(k = 4; k <= 8 ; k+=2){
grille * g = creer_grille(k);
assert(g->n == k && "Problème dans le champ n de la grille");
//Vérification que les cellules sont vides
for(i = 0 ; i < k * k ; i++){
assert(g->tab[i].val == -1 && "Problème : cellule non vide !");
assert(g->tab[i].initial == 0 && "Problème : cellule initiale !");
}
detruire_grille(g);
}
printf("Test de la fonction creer_grille OK !\n");
}
int main()
{
test_creer_grille();
}
Upvotes: 0
Views: 61
Reputation: 30926
g->n = n;
This is accessing an uninitalized value - invoking Undefined Behavior in your code. Move the line to after you allocate using malloc
.
Also g = malloc(sizeof(int) * (n*n));
is wrong you don't want grille*
to point to a chunk which is allocated for int
's. because in case there is not enough memory there will be undefined behavior acessing memory out of your allocation.
g = malloc(sizeof(*g) * (n));
As you have allocated the n*n
locations for storing grille
you should access them by indexing
for (i = 0; i < n; i++)
{
// for some x
g[i].tab[x].val = -1;
g[i].tab[x].initial = 0;
}
Again g->tab[i].val = -1;
this is wrong because of the same reason pointed earlier. You have to allocate memory to g[i].tab
. Otherwise it's undefined behavior. You have to allocate memory for g[i].tab
.
g[i].tab = malloc(sizeof *g[i].tab * someSize);
Also there is a flaw in your logic. First of all allocating nxn
memory doesn't mean you have nxn
grid. The method you followed will give you a contiguous chunk of nxn
elements and that will not be of that use. (You can make a use of it but that's an overkill).
The best thing you can do is a jagged array and it's example is shown here.
Example code:-
grille *creer_grille(int n)
{
grille *g;
g = malloc(sizeof *g * n);
if( g == NULL){
fprintf(stderr,"%s\n","Error in malloc");
exit(1);
}
for (size_t i = 0; i < n; i++)
{
g[i].tab = malloc(sizeof *g[i].tab * n);
if( g[i].tab == NULL){
fprintf(stderr, "%s\n", "Error in malloc");
exit(1);
}
g[i].n = n;
for(size_t j = 0; j < n; j++){
g[i].tab[j].val = -1;
g[i].tab[j].initial = 0;
}
}
return g;
}
You have to free
the dynamically allocated memory after you are done working with it. The free
logic would be something like - you will first free the memory allocated in tab
and then after all of those memory is freed, you will free memory allocated in g
.
Upvotes: 3