Segfault incompréhensible (langage C)

Fermé
Akah - 4 janv. 2009 à 17:59
 Akah - 5 janv. 2009 à 18:36
Bonjour,
tout d'abord bonnes fêtes à vous.
Je suis débutant en C, et donc me retrouve coincé pour un segfault dont je n'arrive pas à trouver la source. Il s'agit d'une histoire de pointeur, je pense. Le compilateur (gcc) compile sans erreur, et au lancement, je ne me retrouve qu'avec l'erreur segfault. La seule chose que je sais est que l'ouverture fonctionne bien, c'est au niveau de "IMAGE* allocation_calque(FILE* fichier)" que le problème est. Je vous joins mon code, au cas où vous trouviez.
Petite précision, l'image ouverte est un fichier .ppm "P6", et les 4 premières lignes que je parcoure sont des renseignements sur l'image, que je stocke pour plus tard.
#include <stdio.h>

#include <stdlib.h>

struct image {
		char* type_image;
		char* commentaires;

		int largeur;
		int longueur;		
		int nuances;
		int* tableau_image;

			

};

	typedef struct image IMAGE;

struct calque {

		IMAGE* image;
		int opacite;
		int* calque_precedent;

		int* calque_suivant;	

};

	typedef struct calque CALQ;



//ouverture du fichier image
	FILE* open(){

		char nomfic[255];

		printf("Entrez le nom du fichier image \n");

		scanf("%s",nomfic); // Pas de & car pointeur

	

		FILE* f;

		f=fopen(nomfic,"r+");

	

		if (f!=NULL){

			printf("Ouverture du fichier \n");

		}

	

		else {

			printf("Erreur dans l'ouverture \n");

		}

		return f;
	}

//fermeture du fichier image
	void close(FILE* fichier){

		

	int result = fclose(fichier);

	

		if (result==0){

			printf("La fermeture est un succes \n");

		}

	

		else {

			printf("Erreur dans la fermeture \n");

		}

	}

//allocation de mémoire pour un calque
IMAGE* allocation_calque(FILE* fichier){

	IMAGE* image;
	int largeur_lue;
	int longueur_lue;
	int niveau_couleur;
	char* type_dimage;
	char* commentaire;
	

		//lecture de l'entête de l'image pour définir les caractéristiques de l'image avec fgets et fscanf
		
		
		fgets(type_dimage, 255, fichier);
		fgets(commentaire, 255, fichier);
		fscanf(fichier,"%d %d",largeur_lue,longueur_lue);
		fscanf(fichier, "%d", niveau_couleur);

		image->type_image=type_dimage;
		image->commentaires=commentaire;
		image->largeur=largeur_lue;
		image->longueur=longueur_lue;

		image->nuances=niveau_couleur;

	return image;

		
}

main(){
	IMAGE* image;
	FILE* fichier;
	fichier=open();

	image=allocation_calque(fichier);
	printf("%s \n",image->type_image);
	printf("%s \n",image->commentaires);
	printf("%d \n",image->largeur);
	printf("%d \n",image->longueur);
	if (fichier!=NULL){
			close(fichier);
		}
}
 


Dans tous les cas, je vous remercie d'avoir jeté un oeil sur mon problème.
Cordialement, Akah.
A voir également:

3 réponses

fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
5 janv. 2009 à 18:30
Salut,

Tu n'as pas tenu compte des erreurs déjà signalées (allocation, ...).
Teste :
#include <stdio.h>
#include <stdlib.h>

typedef struct STRUCT_IMAGE IMAGE;
struct STRUCT_IMAGE {
    char type_image[255];
    char commentaires[255];
    int largeur;
    int longueur;		
    int nuances;
    int* tableau_image;

};


typedef struct calque CALQ;
struct calque {
    IMAGE* image;
    int opacite;
    int* calque_precedent;
    int* calque_suivant;	
};



//ouverture du fichier image
FILE* open(void){

    char nomfic[255];
    printf("Entrez le nom du fichier image \n");
    scanf("%s",nomfic); // Pas de & car pointeur

    FILE* f;
    f=fopen(nomfic,"r+");

    if (f!=NULL){
        printf("Ouverture du fichier \n");
    }

    else {
        printf("Erreur dans l'ouverture \n");
    }
    return f;
}

//fermeture du fichier image
void close(FILE* fichier){

    int result = fclose(fichier);

    if (result==0){
        printf("La fermeture est un succes \n");
    }

    else {
        printf("Erreur dans la fermeture \n");
    }
}

//allocation de mémoire pour un calque
IMAGE* allocation_calque(FILE* fichier){


    IMAGE* image=malloc(1*sizeof(IMAGE));
    if (image==NULL){
        printf("allocation impossible");
    }

    else{

        //lecture de l'entête de l'image pour définir les caractéristiques de l'image avec fgets et fscanf
        fgets(image->type_image, 255, fichier);
        fgets(image->commentaires, 255, fichier);
        fscanf(fichier,"%d %d",&image->largeur,&image->longueur);
        fscanf(fichier, "%d", &image->nuances);
    }

    return image;
}

int main(void){
    IMAGE* image;
    FILE* fichier;
    fichier=open();
    image=allocation_calque(fichier);
    puts(image->type_image);
    puts(image->commentaires);
    printf("%d \n",image->largeur);
    printf("%d \n",image->longueur);
    if (fichier!=NULL){
        close(fichier);
    }

    return 0;
}


Je t'ai changé plusieurs trucs. S'il faut impérativement des pointeurs dans ta structure, il te faudra réaliser une allocation dynamique. Ici, j'ai plutôt utilisé des tableaux de chars ;)

Cdlt
1
Merci beaucoup, cela fonctionne.
Je vais patiemment relire ce que vous avez fait pour bien comprendre, et éviter de retomber dans les mêmes travers.
En vous remerciant encore,
Akah
0
chuka Messages postés 965 Date d'inscription samedi 11 octobre 2008 Statut Membre Dernière intervention 29 juillet 2010 378
4 janv. 2009 à 19:19
Salut,
Si tu n'alloues pas d'espace mémoire pour tes pointeurs, tu risques d'avoir beaucoup de segment fault.....notamment quand tu vas vouloir leur affecter des valeurs....
par exemple tu fais cela:
main(){
IMAGE* image;
FILE* fichier;
fichier=open();
image=allocation_calque(fichier);//donc appel de la fonction allocation_calque et dans cette fonction tu affectes des valeur à un pointeurs de type IMAGE mais nulle part tu as notifié quelle adresse mémoire...donc segment fault en runtime.....
tu pourrais faire un truc du genre dans la fonction:
IMAGE* allocation_calque(FILE* fichier){

IMAGE* image=(IMAGE*)malloc (sizeof(IMAGE));

J'espère ça pourra t'aider!!!

@+
0
Quelques petites erreurs:
- les fonctions du type 'scanf' attendent des pointeurs sur les variables (sinon elles ne pourraient retourner la valeur saisie), donc: fscanf(fichier, "%d", &niveau_couleur);
- la fonction 'main' est de type "int' et doit donc retourner une valeur.
0
Merci à vous deux, je regarde ça et vous fais part de mon avancement.
Cordialement, Akah
0
Bonsoir. Me revoilà...malheureusement, bien que vos remarques aient été pertinentes, elles n'ont pas résolu mon problème : il est resté le même.
Il me semble qu'en fait, le programme ne veut même pas rentrer dans la fonction allocation_calque(), car lorsque j'y mets un printf en tout début, celui-ci ne veut même pas s'afficher dans la console.
Je vous repropose donc mon code, parce que je ne trouve toujours pas :

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

struct STRUCT_IMAGE {
		char* type_image;
		char* commentaires;
		int largeur;
		int longueur;		
		int nuances;
		int* tableau_image;
			
};
	typedef struct STRUCT_IMAGE IMAGE;

struct calque {
		IMAGE* image;
		int opacite;
		int* calque_precedent;
		int* calque_suivant;	
};
	typedef struct calque CALQ;



//ouverture du fichier image
	FILE* open(){

		char nomfic[255];
		printf("Entrez le nom du fichier image \n");
		scanf("%s",nomfic); // Pas de & car pointeur
	
		FILE* f;
		f=fopen(nomfic,"r+");
	
		if (f!=NULL){
			printf("Ouverture du fichier \n");
		}
	
		else {
			printf("Erreur dans l'ouverture \n");
		}
		return f;
	}

//fermeture du fichier image
	void close(FILE* fichier){
		
	int result = fclose(fichier);
	
		if (result==0){
			printf("La fermeture est un succes \n");
		}
	
		else {
			printf("Erreur dans la fermeture \n");
		}
	}

//allocation de mémoire pour un calque
IMAGE* allocation_calque(FILE* fichier){


	IMAGE* image=(IMAGE*)malloc(1*sizeof(IMAGE));
	if (image==NULL){
		printf("allocation impossible");
	}

	else{

		int largeur_lue;
		int longueur_lue;
		int niveau_couleur;
		char* type_dimage;
		char* commentaire;
	

		//lecture de l'entête de l'image pour définir les caractéristiques de l'image avec fgets et fscanf
		
		
		fgets(type_dimage, 255, fichier);
		fgets(commentaire, 255, fichier);
		fscanf(fichier,"%d %d",&largeur_lue,&longueur_lue);
		fscanf(fichier, "%d", &niveau_couleur);

		image->type_image=type_dimage;
		image->commentaires=commentaire;
		image->largeur=largeur_lue;
		image->longueur=longueur_lue;
		image->nuances=niveau_couleur;

	return image;
	}

		
}

void main(){
	IMAGE* image;
	FILE* fichier;
	fichier=open();
	image=allocation_calque(fichier);
	printf("%s \n",image->type_image);
	printf("%s \n",image->commentaires);
	printf("%d \n",image->largeur);
	printf("%d \n",image->longueur);
	if (fichier!=NULL){
			close(fichier);
		}
}



Cordialement, Akah
0