C 代码编译,但在使用游戏板运行时给出segmentationfault 问题
我的最终目标是为这样的游戏打开一个游戏板:然后把它当作大学作业来玩。我在国外,不能总是听懂讲师说的每一句话 我的问题是我在pile.c中思考——下面的第三段代码。我已经在gdb中发现了这一点,我对此非常缺乏经验:我已经从代码中删除了注释,因此行号是不正确的——但它仍然指出它所指的行存在调试问题C 代码编译,但在使用游戏板运行时给出segmentationfault 问题,c,pointers,struct,segmentation-fault,C,Pointers,Struct,Segmentation Fault,我的最终目标是为这样的游戏打开一个游戏板:然后把它当作大学作业来玩。我在国外,不能总是听懂讲师说的每一句话 我的问题是我在pile.c中思考——下面的第三段代码。我已经在gdb中发现了这一点,我对此非常缺乏经验:我已经从代码中删除了注释,因此行号是不正确的——但它仍然指出它所指的行存在调试问题 Program received signal SIGSEGV, Segmentation fault. 0x0000000000400ee6 in afficher_pile (pile=...) at
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400ee6 in afficher_pile (pile=...) at pile.c:48
48 afficher(P_elt->valeur);//########DEBUGGING PROBLEM
在我看来,非常简单的afficher打印函数指的是不应该指的东西,但我基本上按照讲师的建议编辑了他提供给我们的一些简单字符串操作函数,其中类型或结构是一个字符和指向下一个字符的指针,如果我正确地理解了空指针,那么链的末端就是hadif
我对编程非常陌生,但我们对结构有相当广泛的指导,因此它们应该是适当和正确的,就像pile.c函数一样
我试过的
起初,我认为我错误地传递了元素的valeur部分,所以我尝试更改afficherP_elt->valeur;以各种方式:
阿菲切普·埃特·瓦勒尔
阿菲彻*p_elt.valeur
阿菲舍尔和p_elt.valeur
这三个不是在结构或联合中编译成员valeur
afficher&p_elt->valeur;编译错误:应为“POSITION”,但参数的类型为“struct POSITION”*
附件*p_elt->valeur;编译错误:一元“*”的无效类型参数具有“位置”
我一直在寻找这样的问题:
我对此抱有希望,但我不认为这是我的错误,我确信我的代码确实使用空指针初始化了结构
基本上,我还没有找到其他可以尝试的东西,我希望在最后一次与讲师讨论问题之前取得更多进展
代码如下
1.proj.h头文件N.B.其中包含一些我尚未编写的函数的原型
2.proj.c将是主文件,目前进展不大
3.pile.c包含gdb突出显示的导致分段错误的代码,还包含用于操纵位置列表的函数,最终玩家和解算器将使用这些位置来解算游戏
4.allocate_plat.c读取程序先前加载的游戏文件,并从游戏文件中显示网格。这可能就是问题所在,因为这里用游戏板上的值初始化了桩结构
5.makefile可能不是必需的,但之前发现它包含一个问题
6.plateau1.txt这似乎至少可以从预览中正确地复制到文本编辑器中-应该没有尾随空格,尽管我不知道这是否重要
1.项目h
2.项目c
P>>4。C。N.B.在中间含有一些重复的FcSnFs,这是我非常确定的工作。
#include <stdio.h>
#include <stdlib.h>
#include "proj.h"
int allouer(PLATEAU *PLAT, int nl, int nc, int ldep, int cdep, int larr, int carr, int longdem, int sumdem){
int i,succes;
PLAT->grille = (int**)calloc(nl,sizeof(int*));
PLAT->nl = nl;
PLAT->nc = nc;
PLAT->longdem = longdem;
PLAT->sumdem = sumdem;
PLAT->dep.indl = ldep;
PLAT->dep.indc = cdep;
PLAT->arr.indl = larr;
PLAT->arr.indc = carr;
succes = (PLAT->grille != NULL);
for (i=0; succes && i<nl;i++){
PLAT->grille[i]=(int*)calloc(nc,sizeof(int));
succes = (PLAT->grille[i] != NULL);
}
return succes;
}
int lire(char *nom_fichier, PLATEAU *PLAT){
int i,j,succes, c;
FILE *fp;
fp = fopen(nom_fichier, "rt");
if(fp==NULL) {
printf("Erreur d'ouverture du fichier\n");
return 0;
}
c = fscanf(fp,"%d %d",&PLAT->nl,&PLAT->nc);//Read first line
if( c != 2){
printf("Erreur de format de fichier\n");
fclose(fp);
return 0;
}
c = fscanf(fp,"%d %d",&i,&j);//Read second line
PLAT->dep.indl=i-1;
PLAT->dep.indc=j-1;
if( c != 2){
printf("Erreur de format de fichier\n");
fclose(fp);
return 0;
}
c = fscanf(fp,"%d %d",&i,&j);//Read third line
PLAT->arr.indl=i-1;
PLAT->arr.indc=j-1;
if( c != 2){
printf("Erreur de format de fichier\n");
fclose(fp);
return 0;
}
c = fscanf(fp,"%d %d",&PLAT->longdem,&PLAT->sumdem);//Read fourth line
if( c != 2){
printf("Erreur de format de fichier\n");
fclose(fp);
return 0;
}
if( c != 2){
printf("Erreur de format de fichier\n");
fclose(fp);
return 0;
}
//ALLOCATE THE FILE TO THE STRUCT
succes = allouer(PLAT, PLAT->nl, PLAT->nc, PLAT->dep.indl, PLAT->dep.indc, PLAT->arr.indl, PLAT->arr.indc, PLAT->longdem, PLAT->sumdem );
if(succes==0) {
printf("Erreur d'allocation\n");
fclose(fp);
return 0;
}
for(i=0; i< PLAT->nl; i++){
for(j=0; j<PLAT->nc; j++){
c=fscanf(fp, "%d", &PLAT->grille[i][j]);
if(c != 1){
printf("Erreur de format de fichier\n");
fclose(fp);
return 0;
}
}
}
fclose(fp);
ELEMENT *P_sommet = nouvel_element(PLAT->dep);
if (P_sommet==NULL){
printf("Erreur d'allocation\n");
return 0;
}
empiler (&PLAT->chemin,P_sommet);
PLAT->longcur=1;
PLAT->sumcur=PLAT->grille[PLAT->dep.indl][PLAT->dep.indc];
//ABOVE LINE INITIALISES THESE THINGS WHEN THE FILE IS READ
return 1;
}
//AFFICHE - PRINT GRILL ONLY
void affiche_grille(PLATEAU jeu){
int i,j;
printf("\nEtat du jeu\n");
for(i=0; i < jeu.nl; i++){
for(j=0; j < jeu.nc; j++){
if (jeu.dep.indl == i && jeu.dep.indc == j){
printf("D %d\t", jeu.grille[i][j]);
}
else if (jeu.arr.indl == i && jeu.arr.indc == j){
printf("%d A\t", jeu.grille[i][j]);
}
else printf("%d\t",jeu.grille[i][j]);
}
printf("\n");
}
printf("\n");//Final new line
}
6.示例游戏文件plateau1.txt,第一行是行和列,第二行和第三行是起始和结束坐标,第四行是所需路径长度和所需网格值之和,最后四行是网格
4 4
1 1
4 4
11 96
10 13 2 5
3 15 9 4
8 6 11 14
7 12 1 16
您有许多未初始化的指针。例如,你从来没有调用过initialiser\u pile。 -巴尔马 在allocate_plat中,在lire末尾的empiler之前调用initialiser_pile有助于感谢。不再是分割错误。
–Luskentyrian您有许多未初始化的指针。例如,您从不调用initialiser\u pile。在main中,您声明元素*P\u elt,但从不分配它。但这没关系,因为你也从来没有使用过。在分配平台的lire末尾,在empiler之前调用initialiser\u pile会有帮助,谢谢。不再是分段错误。在循环中,最后一个元素永远不会为空,除非,由于偶然的机会,因为您从未初始化它。P_elt!=NULL总是真的。因此,循环继续超出元素范围,并访问导致SEGFULT的一些随机地址。
#include <stdio.h>
#include <stdlib.h>
#include "proj.h"
////////// AFFICHER POSITION ////////////////////////////
int afficher(POSITION v){
printf("\t%d %d", v.indl,v.indc);
}
///////// NOUVEL_ELEMENT /////////////////////////////
ELEMENT *nouvel_element (POSITION nouvelle_valeur){
ELEMENT *P_elt;
P_elt =(ELEMENT*) malloc(sizeof(ELEMENT));
if(P_elt ) {
P_elt->valeur= nouvelle_valeur;
P_elt->P_suivant=NULL;
}
return P_elt;
}
/////////////////////////////////////////////////////
void initialiser_pile(PILE *P_pile){
P_pile->P_sommet=NULL;
}
////////////EST VIDE /////////////////////////////////////////
int est_vide (PILE pile){
return pile.P_sommet == NULL;//i.e. true (non-zero) if P_sommet is NULL
}
////////// AFFICHER PILE PRINT PATH //////////////////
int afficher_pile (PILE pile){
ELEMENT *P_elt;
int l=0;
for(P_elt= pile.P_sommet ; P_elt!=NULL ; P_elt=P_elt->P_suivant, l++ )
afficher(P_elt->valeur);//######## DEBUGGING PROBLEM #################
return l;
}
/////////// LENGTH OF PATH //////////////////////////
int longueur_pile (PILE pile){
ELEMENT *P_elt;
int l=0;
for(P_elt= pile.P_sommet ; P_elt!=NULL ; P_elt=P_elt->P_suivant )
l++;
return l;
}
///////////EMPILER ADD ELEMENT TO PATH //////////////
ELEMENT* empiler(PILE *P_pile, ELEMENT *P_elt_ajoute){
P_elt_ajoute ->P_suivant = P_pile->P_sommet; /*on chaine P_elt_ajoute a la suite */
P_pile->P_sommet = P_elt_ajoute; /*on chaine la sommet a P_elt_ajoute */
return P_elt_ajoute;
}
/////////DEPILER REMOVE ELEMENT FROM PATH///////////
ELEMENT* depiler (PILE *P_pile){
ELEMENT *P_elt_supprime;
/* Si la pile est vide */
if (est_vide(*P_pile))
return NULL;
/* Si la pile n'est pas vide */
P_elt_supprime=P_pile->P_sommet ;
P_pile->P_sommet = P_elt_supprime->P_suivant; /*on chaine la sommet a la suite */
P_elt_supprime->P_suivant=NULL; /* on supprime le chainage de P_elt_supprime */
return P_elt_supprime;
}
//*
/////////////// LIRE SOMMET ////////////////////////
POSITION lire_sommet (PILE *P_pile){
ELEMENT *P_elt;
// if (est_vide(*P_pile))
// return NULL; //sortie fonction
for(P_elt = P_pile->P_sommet; P_elt->P_suivant != NULL; P_elt = P_elt->P_suivant);
return P_elt->valeur;
}
#include <stdio.h>
#include <stdlib.h>
#include "proj.h"
int allouer(PLATEAU *PLAT, int nl, int nc, int ldep, int cdep, int larr, int carr, int longdem, int sumdem){
int i,succes;
PLAT->grille = (int**)calloc(nl,sizeof(int*));
PLAT->nl = nl;
PLAT->nc = nc;
PLAT->longdem = longdem;
PLAT->sumdem = sumdem;
PLAT->dep.indl = ldep;
PLAT->dep.indc = cdep;
PLAT->arr.indl = larr;
PLAT->arr.indc = carr;
succes = (PLAT->grille != NULL);
for (i=0; succes && i<nl;i++){
PLAT->grille[i]=(int*)calloc(nc,sizeof(int));
succes = (PLAT->grille[i] != NULL);
}
return succes;
}
int lire(char *nom_fichier, PLATEAU *PLAT){
int i,j,succes, c;
FILE *fp;
fp = fopen(nom_fichier, "rt");
if(fp==NULL) {
printf("Erreur d'ouverture du fichier\n");
return 0;
}
c = fscanf(fp,"%d %d",&PLAT->nl,&PLAT->nc);//Read first line
if( c != 2){
printf("Erreur de format de fichier\n");
fclose(fp);
return 0;
}
c = fscanf(fp,"%d %d",&i,&j);//Read second line
PLAT->dep.indl=i-1;
PLAT->dep.indc=j-1;
if( c != 2){
printf("Erreur de format de fichier\n");
fclose(fp);
return 0;
}
c = fscanf(fp,"%d %d",&i,&j);//Read third line
PLAT->arr.indl=i-1;
PLAT->arr.indc=j-1;
if( c != 2){
printf("Erreur de format de fichier\n");
fclose(fp);
return 0;
}
c = fscanf(fp,"%d %d",&PLAT->longdem,&PLAT->sumdem);//Read fourth line
if( c != 2){
printf("Erreur de format de fichier\n");
fclose(fp);
return 0;
}
if( c != 2){
printf("Erreur de format de fichier\n");
fclose(fp);
return 0;
}
//ALLOCATE THE FILE TO THE STRUCT
succes = allouer(PLAT, PLAT->nl, PLAT->nc, PLAT->dep.indl, PLAT->dep.indc, PLAT->arr.indl, PLAT->arr.indc, PLAT->longdem, PLAT->sumdem );
if(succes==0) {
printf("Erreur d'allocation\n");
fclose(fp);
return 0;
}
for(i=0; i< PLAT->nl; i++){
for(j=0; j<PLAT->nc; j++){
c=fscanf(fp, "%d", &PLAT->grille[i][j]);
if(c != 1){
printf("Erreur de format de fichier\n");
fclose(fp);
return 0;
}
}
}
fclose(fp);
ELEMENT *P_sommet = nouvel_element(PLAT->dep);
if (P_sommet==NULL){
printf("Erreur d'allocation\n");
return 0;
}
empiler (&PLAT->chemin,P_sommet);
PLAT->longcur=1;
PLAT->sumcur=PLAT->grille[PLAT->dep.indl][PLAT->dep.indc];
//ABOVE LINE INITIALISES THESE THINGS WHEN THE FILE IS READ
return 1;
}
//AFFICHE - PRINT GRILL ONLY
void affiche_grille(PLATEAU jeu){
int i,j;
printf("\nEtat du jeu\n");
for(i=0; i < jeu.nl; i++){
for(j=0; j < jeu.nc; j++){
if (jeu.dep.indl == i && jeu.dep.indc == j){
printf("D %d\t", jeu.grille[i][j]);
}
else if (jeu.arr.indl == i && jeu.arr.indc == j){
printf("%d A\t", jeu.grille[i][j]);
}
else printf("%d\t",jeu.grille[i][j]);
}
printf("\n");
}
printf("\n");//Final new line
}
CC = gcc
CFLAGS = -I . #-Wall
DEPS = proj.h
OBJ = proj.o allocate_plat.o pile.o grille.o
%.o: %.c $(DEPS)
$(CC) $(CFLAGS) -g -c -o $@ $<
proj: $(OBJ)
gcc $(CFLAGS) -g -o $@ $^
4 4
1 1
4 4
11 96
10 13 2 5
3 15 9 4
8 6 11 14
7 12 1 16