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 :

[Aide] problème de segmentation mémoire


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 19
    Points : 28
    Points
    28
    Par défaut [Aide] problème de segmentation mémoire
    Bonjour à tous,

    pour mon premier message ici, je commence par vous demander un avis extérieur.

    Je travaille sur un projet de simulation de magasin en C, et bien que le code passe la compilation (entre autres grâce aux conseils trouvés ici), j'obtiens un message "Erreur de segmentation (core dumped)" à l'éxecution.
    Mon 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
    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <math.h>
     
    #define MAXP 5
    #define MAXC 50
    //numero d'id, tableau entier chariot
    struct Client
    {
    int id;
    int *chariot;
    };
     
    typedef struct Client Client;
     
    double Moyenne (int* moyenne)
    {
    	double somme;
    	for (int i=0; i<MAXP; i=i++)
    	{
    		somme+=(double)*(moyenne+i);
    	}
    	somme/=MAXP;
    	return somme;
    }
     
    double Quadratique(int* moyenne)
    {
    	double somme;
    	for (int i=0; i<MAXP; i=i++)
    	{
    		somme+=(double)((*(moyenne+i))*(*(moyenne+i)));
    	}
    	somme/=MAXP;
    	return sqrt(somme);
    }
     
    double Cube(int* moyenne)
    {
    	double somme;
    	for (int i=0; i<MAXP; i=i++)
    	{
    		somme+=(double)((*(moyenne+i))*(*(moyenne+i))*(*(moyenne+i)));
    	}
    	return somme;
    }
    int main()
    {
    	clock_t temps;
    	int prix, i;
    	Client *p=(Client *) malloc(MAXC*sizeof(struct Client));
    	srand(time(NULL));
    	double histo[MAXC][3];
    	for(i=0;i<MAXC;i++)
    	{
    		Client Cl;
    		Cl.id=i++;
    		Cl.chariot=(int *) malloc(MAXP*sizeof(int));
    		*(p+i)=Cl;
    	}
    	for(i=0;i<MAXC;i++)
    	{
    		for(int j=0;j<MAXP;j++)
    		{
    			Client tmp;
    			tmp=*(p+i);
    			tmp.chariot[j]=(rand()%49)+1;
    		}
    	}
    	for(i=0;i<MAXC;i++)
    	{
    		Client tmp;
    		tmp=*(p+i);
    		histo[i][0]=Moyenne(tmp.chariot);
    		histo[i][1]=Quadratique(tmp.chariot);
    		histo[i][2]=Cube(tmp.chariot);
    	}
    	free(p);
    	for(i=0;i<MAXC;i++)
    	{
    		printf("Ticket du client %d : %f %f %f",i++,histo[i][0],histo[i][1],histo[i][2]);
    	}
    	printf("Temps total d'execution : %f",(double)temps/CLOCKS_PER_SEC);
    }
    Je pense que le problème vient du seul tableau que je déclare en statique dans mon algorithme, mais je n'arrive pas à le transformer en un tableau dynamique.

    Ai-je trouvé la cause du problème ? Si oui, que puis-je faire pour y remédier ?
    Mon algorithme est-il juste bon pour la corbeille ?

    Merci d'avance,

    Vrashnak

    EDIT : je viens de me rendre compte que j'ai posté dans la mauvaise rubrique... Désolé :S
    Si un gentil modérateur veut bien déplacer ce sujet...

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour, et bienvenue sur le forum DVP

    1. typedef struct Client Client; Personnellement, je n'aime pas trop que la structure et son alias aient le même nom
    2. Dans tes fonctions Moyenne() , Quadratique() et Cube() : i=i++ i++ suffit (tu fais une affectation i=i; pour rien, puis incrémentes i).
    3. Lignes 58 Cl.id=i++; et 82
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      printf("Ticket du client %d : %f %f %f",i++,histo[i][0],histo[i][1],histo[i][2]);
      attention i++ incrémente ta variable i, étant aussi incrémentée à la ligne for(...), tu loupes 1 valeur sur 2. ++ à supprimer donc.
    4. pointeur[i] un peu plus léger que *(pointeur+i).
    5. Dans Cube() somme/=MAXP; manquant ?
    6. free(p); tout seul est incorrect : tu ne libères que le malloc de la ligne
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      Client *p=(Client *) malloc(MAXC*sizeof(struct Client));

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      for(i=0;i<MAXC;i++) 
      {
          free(p[i].chariot);
      }
      free(p);
    7. Première boucle : Client Cl; est une variable temporaire créée indépendamment de p, donc faire *(p+i)=Cl; est incorrect : il faut utiliser l'espace alloue par le malloc

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      Client *Cl;
      Cl = p+i;
    8. somme à initialiser à 0 dans tes fonctions, sinon valeur indéterminée.

    Voilà c'est à peu près tout
    Dernière modification par Invité ; 06/10/2012 à 20h32. Motif: Ajout

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 19
    Points : 28
    Points
    28
    Par défaut
    Merci Winjerome de ta réponse

    Pour Cube(), il me faut juste la somme des cubes (c'est écrit comme ça dans l'énoncé du projet... Je n'ai aucune idée de pourquoi il faut la somme ici et les moyennes sinon... Le prof a raison, n'est-ce-pas ?).
    Pour les pointeurs, là encore le sujet demande que l'on montre au moins une fois que l'on sait utiliser les pointeurs de cette façon. Sinon, je m'en serai bien passé... (je me mélange en permanence les pinceaux le & et le *)

    Sinon, j'ai appliqué les modifications que tu m'as proposé (merci d'avoir pris le temps de lire mon algo d'ailleurs...), mais j'ai encore mon erreur de segmentation. Apparemment, ce genre d'erreurs n'arrive que lorsque l'on déclare une variable qui veut aller s'enregistrer à l'emplacement d'une autre, et boum la variable !

    Revoilà le code corrigé (excepté ce que je dois laisser...)

    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <math.h>
     
    #define MAXP 5
    #define MAXC 50
    //numero d'id, tableau entier chariot
    struct Cli
    {
    int id;
    int *chariot;
    };
     
    typedef struct Cli Client;
     
    double Moyenne (int* moyenne)
    {
    	double somme;
    	for (int i=0; i<MAXP; i++)
    	{
    		somme+=(double)*(moyenne+i);
    	}
    	somme/=MAXP;
    	return somme;
    }
     
    double Quadratique(int* moyenne)
    {
    	double somme;
    	for (int i=0; i<MAXP; i++)
    	{
    		somme+=(double)((*(moyenne+i))*(*(moyenne+i)));
    	}
    	somme/=MAXP;
    	return sqrt(somme);
    }
     
    double Cube(int* moyenne)
    {
    	double somme;
    	for (int i=0; i<MAXP; i++)
    	{
    		somme+=(double)((*(moyenne+i))*(*(moyenne+i))*(*(moyenne+i)));
    	}
    	return somme;
    }
    int main()
    {
    	clock_t temps;
    	int prix, i;
    	Client *p=(Client *) malloc(MAXC*sizeof(struct Cli));
    	srand(time(NULL));
    	double histo[MAXC][3];
    	for(i=0;i<MAXC;i++)
    	{
    		Client Cl;
    		Cl.id=i++;
    		Cl.chariot=(int *) malloc(MAXP*sizeof(int));
    		*(p+i)=Cl;
    	}
    	for(i=0;i<MAXC;i++)
    	{
    		for(int j=0;j<MAXP;j++)
    		{
    			p[i].chariot[j]=(rand()%49)+1;
    		}
    	}
    	for(i=0;i<MAXC;i++)
    	{
    		Client tmp;
    		tmp=*(p+i);
    		histo[i][0]=Moyenne(tmp.chariot);
    		histo[i][1]=Quadratique(tmp.chariot);
    		histo[i][2]=Cube(tmp.chariot);
    	}
    	for(i=0;i<MAXC;i++) 
    	{
        	free(p[i].chariot);
    	}
    	free(p);
    	for(i=0;i<MAXC;i++)
    	{
    		printf("Ticket du client %d : %f %f %f",i,histo[i][0],histo[i][1],histo[i][2]);
    	}
    	printf("Temps total d'execution : %f",(double)temps/CLOCKS_PER_SEC);
    }
    Que puis-je faire ?

    Merci encore,

    Vrashnak

    PS : je consulte le site depuis un an à peu près, mais je viens juste de m'inscrire. Je dois dire qu'il m'a aidé pas mal de fois...
    Sinon, et je demande un avis totalement subjectif : d'un point de vue codage, c'est à peu près correct ou pas ? (Le code est propre, pas de grosse erreur d'écriture, je ne maltraite pas le C...)

  4. #4
    Invité
    Invité(e)
    Par défaut
    J'ai rajouté entre temps quelques points que tu n'as pas du voir... je te laisse les consulter.
    Attention à la première partie de mon 3ème : ligne 58.
    Autre remarque : en C le cast après malloc n'est pas nécessaire.

    Sinon oui dans l'ensemble c'est plutôt correct

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 19
    Points : 28
    Points
    28
    Par défaut
    Je dois vraiment être nul...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for(i=0;i<MAXC;i++)
    	{
    		Client *Cl;
    		*Cl.id=i;
    		*Cl.chariot=(int *) malloc(MAXP*sizeof(int));
    		*(p+i)=*Cl;
    	}
    Et ça me donne ça à la compilation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [till_gray@Reghar Theorie_Systeme_Exploitation]$ gcc Sequentiel.c -std=c99 -lm -o seq
    Sequentiel.c: In function ‘main’:
    Sequentiel.c:58:6: erreur: request for member ‘id’ in something not a structure or union
    Sequentiel.c:59:6: erreur: request for member ‘chariot’ in something not a structure or union
    (j'ai mis seulement le bout de code qui nous intéresse... le for() est ligne 55)

    Merci Winjerome !!!
    J'ai corrigé aussi la ligne 58.
    Par contre, le cast de malloc n'est pas nécessaire ? On a vu en cours qu'il le fallait... On m'aurait menti ?
    Du coup, mon cast ne sert à rien ? Le malloc n'a pas besoin d'être casté ?

  6. #6
    Invité
    Invité(e)
    Par défaut
    Faut-il caster malloc ?

    Alors deux choses qui ne vont pas dans ton code :
    1. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      Client *Cl;
      *Cl.id=i;
      Là déjà, Cl n'est pas initialisé et ne pointe sur aucun espace mémoire valide. Tu ne peux donc rien faire dessus. Comme montré : Cl = p+i; qui va alors pointer sur le bon espace alloué sur p.
    2. Les syntaxes : *Cl.id et *Cl.chariot sont incorrectes, Cl étant un pointeur, il te faut utiliser l'opérateur -> sur les éléments de la structure Cl->id et Cl->chariot

    On a donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Client *Cl = p+i;
    Cl->id=i;
    Cl->chariot = malloc(MAXP*sizeof(int));
    Enfin dernière petite remarque : tu peux réunir tes 4 boucles for selon MAXC.

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 19
    Points : 28
    Points
    28
    Par défaut
    Merci Winjerome !
    Grâce à tes indications, le code fonctionne. Je n'aurais jamais pu y arriver seul.
    Donc mon problème ne venait pas de mon tableau statique. Moralité : se méfier de ce que l'on trouve sur Internet en cherchant !

    Encore merci ! (Tu seras cité dans mon rapport en tous cas )

    Cordialement,

    Vrashnak.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. FIREBIRD + APPLI EN C : Problèmes de libération mémoire
    Par lio33 dans le forum Connexion aux bases de données
    Réponses: 4
    Dernier message: 16/09/2005, 09h07
  2. Problème de fuite mémoire sur un idFTP
    Par jeromelef dans le forum Composants VCL
    Réponses: 6
    Dernier message: 26/07/2005, 17h29
  3. Problème de segmentation ?
    Par julson dans le forum Assembleur
    Réponses: 2
    Dernier message: 23/12/2004, 18h33
  4. Réponses: 25
    Dernier message: 16/07/2003, 20h41
  5. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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