为什么我会出现段错误?

这是我的代码,我得到一个分段错误,我不知道为什么……我正在创建一个n是它的大小的网格, tab是一个数组,他的类型是cellule:一个单元格有2个值。 所以我在函数creer_grille创建了一个数组我malloc它(大小可以是4 6或8)并且我用-1和0初始化单元格值。然后在下面的函数中我正在测试creer_grille函数。

 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 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 n == k && "Problème dans le champ n de la grille"); //Vérification que les cellules sont vides for(i = 0 ; i 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(); } 

 g->n = n; 

这是访问未初始化的值 – 在代码中调用未定义的行为 。 使用malloc分配后将行移动到。

另外g = malloc(sizeof(int) * (n*n)); 是不对的,你不希望grille*指向为int分配的块。 因为如果没有足够的内存,将会有未定义的行为从你的分配中获取内存。

 g = malloc(sizeof(*g) * (n)); 

由于您已经分配了用于存储grillen*n位置,因此您应该通过索引来访问它们

  for (i = 0; i < n; i++) { // for some x g[i].tab[x].val = -1; g[i].tab[x].initial = 0; } 

再次g->tab[i].val = -1; 这是错误的,因为前面提到的原因相同。 你必须为g[i].tab分配内存。 否则它是未定义的行为。 你必须为g[i].tab分配内存。

  g[i].tab = malloc(sizeof *g[i].tab * someSize); 

你的逻辑也存在一个缺陷。 首先分配nxn内存并不意味着你有nxn网格。 您遵循的方法将为您提供一个连续的nxn元素块,并且不会使用这些元素。 (你可以利用它,但那是一种过度杀伤力)。

你可以做的最好的事情是一个锯齿状的数组,这里展示了它的例子。

示例代码: -

 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; } 

完成后,必须free动态分配的内存。 free逻辑将是这样的 - 你将首先释放在tab分配的内存,然后在释放所有这些内存后,你将释放分配给g内存。