IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Fonction renvoyant **float: "erreur de segmentation" mais pas tout le temps


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 13
    Par défaut Fonction renvoyant **float: "erreur de segmentation" mais pas tout le temps
    Bonjour à tous!

    J'ai un problème sur une fonction (newArray) qui demande à l'utilisateur les valeurs d'un tableau à double entrée. Il prend en entrée un tableau de float prérempli de 0 et retourne ce même tableau avec les valeurs modifiées par l'utilisateur.

    Voici le main (que la partie qui est intéressante):
    (a et b sont des int qui sont rentrées préalablement par l'utilisateur)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    if(emptymat1){
    	mat1=(float **)malloc(a*sizeof(float*));
    	for(i=0;i<a;i++){
    		mat1[i]= (float *)malloc(b*sizeof(float));
    	}
    }
    else{
    	mat1=(float **)realloc(mat1,a*sizeof(float*));
    	for(i=0;i<a;i++){
    		mat1[i]= (float *)realloc(mat1,b*sizeof(float));
    	}
    }
    for(i=0;i<a;i++){
    	for(k=0;k<b;k++){
    		mat1[i][k]=0;
    	}
    }
    mat1=newArray(mat1,a,b);
    et ma fonction newArray:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    float **newArray(float** T,int r,int c){
    	char isNotNull, test='y';
    	float val;
    	int i,j;
     
    	printf("All the elements of the matrix were intialized to 0. ");
    	do{
    		printf("Are there elements in the matrix which are not null? (y/n) ");
    		scanf("%c",&isNotNull);
    		purge();
    	}while(isNotNull!='y' && isNotNull!='n');
    	if(isNotNull=='y'){
    		printf("Please tell which elements of the matrix are not null :\n\n");
    		while(test=='y'){
    			do{
    				printf("Enter the row: ");
    				scanf("%d",&i);
    				purge();
    			}while(i<1 || i>r);
    			do{
    				printf("Enter the column: ");
    				scanf("%d",&j);
    				purge();
    			}while(j<1 || j>c);
     
    			printf("Enter the value of the element (%d,%d) : ",i,j);
    			scanf("%f",&val);
    			purge();
     
    			T[i-1][j-1]= val;
     
    			do{
    				printf("Is there an other non-null element inside the matrix? (y/n)");
    				scanf("%c",&test);
    				purge();
    			}while(test!='y' && test!='n');
    		}
    	}
     
    	return T;
    }
    Voici les problèmes que je rencontre:
    J'ai fait quelques tests avec des matrices, et je ne sais pas pourquoi, des fois ça passe, des fois ça passe pas.
    Imaginons a=b=3.
    Si je mets l'élément (2,1) (donc [1][0] du tableau) à une certaine valeur, et l'élément (2,2) à une autre valeur, tout va bien.
    Mais si par exemple je mets une valeur à l'élément (3,1) (donc [2][0]), il me l'accepte, me demande si d'autres valeurs sont nulles, je réponds "n", et la paf: "erreur de segmentation". L'erreur arriverait donc au niveau du "return T", la dernière ligne de la fonction.
    Je sais que le problème est dans ces lignes car juste après l'appel à la fonction dans le main, j'ai un printf dont le contenu ne s'affiche pas.

    Est-ce que vous voyez une erreur quelque part svp? Merci

  2. #2
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Ca doit être un dépassement de mémoire.

    Par contre, dans ton code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	for(i=0;i<a;i++){
    		mat1[i]= (float *)realloc(mat1,b*sizeof(float));
    	}
    le premier argument devrait être mat1[i].

    Ensuite, il faut tester le retourn de malloc/realloc...

    Enfin, realloc peut retourner NULL, du coup, il faudrait faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void *tmp = realloc (bla);
     
    assert (tmp);
     
    if (tmp != NULL)
       mat1[i] =  tmp;
    Jc

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 13
    Par défaut
    Merci pour ta réponse!

    Quand tu dis que ça peut être dû à un dépassement de mémoire, où est-ce que l'erreur pourrait être?
    Parce que mon erreur de segmentation arrive lorsque emptymat1=true, donc il fait un malloc et non un réalloc.

  4. #4
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    Par défaut
    On ne le repetera jamais assez, toujours verifier les retour de fonction, surtout celle touchant a l'allocation memoire.

    Il faut faire ce type de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    char *test = NULL;
    int nombreLettre = 20;
     
    test = malloc (nombreLettre * sizeof(char));
    if (test == NULL)
    {
        perror("Regarde commet cette fonction marche, il y a plein d'exemple ");
        /* A toi de determiné l'action a faire en cas d'erreur */
    }
    else
    {
        /* La, tu continue ton programme tranquillement */
    }
    Ainsi, si ton malloc est la cause de tes soucis, tu aura un beau message d'erreur dans stderr t'expliquant pourquoi.


    Sinon, je penche moi aussi pour un depassement memoire. En meme temps, segfault sur un tableau allouer dynamiquement, y'a de grande chance que ce soit la.

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 13
    Par défaut
    Ok merci, je n'ai pas le code sous la main, je testerai.

    Mais étant donné que ça marche pour certaines valeurs, ça veut dire que l'allocation de mat1 a bien fonctionné ou en tout cas que mat1!=NULL, non?


    EDIT:
    J'ai ajouté le test du malloc, il ne me met aucune erreur. Mieux, juste avant le return de ma fonction newArray, je fais un print du tableau, et toutes les valeurs ont bien été entrées correctement! Je ne comprends vraiment pas ce qui se passe...

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Ce qui me chagrine dans ton code, c'est la réallocation.
    Outre l'erreur déjà signalée (le premier argument du realloc devrait être mat1[i]) et la remarque que les échecs d'allocations ne sont pas gèrés, la réallocation ne marche pas.

    Appelons an la nouvelle valeur de a et ap la précédente et supposons pour simplifier qu'il n'y a pas d'échec d'allocation :

    1- an < ap Alors après réallocation de mat1, tous les pointeurs de mat1[an-1] à mat1[ap-1] sont perdus. Ceci entraine une fuite mémoire pour les allocations précédentes dont l'adresse est dans ces pointeurs. On doit au préalable libérer la mémoire adressée par ces pointeurs.

    2- an > ap Alors les nouveaux pointeurs de mat1[ap-1] à mat1[an-1] sont créés mais non initialisés et il n'est pas possible de faire un realloc dessus. Il faudrait auparavant les mettre explicitement à NULL.

    A remarquer que cela implique de connaitre l'ancienne première dimension (ap) du tableau.

Discussions similaires

  1. Réponses: 3
    Dernier message: 11/05/2014, 22h24
  2. jQuery erreur "Warning:" parfois mais pas tout le temps
    Par elizabeth dans le forum jQuery
    Réponses: 6
    Dernier message: 02/01/2012, 11h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo