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 :

Problème allocation dynamique ?


Sujet :

C

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 25
    Points : 7
    Points
    7
    Par défaut Problème allocation dynamique ?
    Bonsoir tout le monde. Voilà mon programme compile sans erreurs mais plante quand je l'execute (dès que je rentre le 1er mot).
    Je pense que c'est un problème d'allocation dynamique mais je ne vois pas où se trouve mon erreur ni Visual Studio d'alleurs ! J'aurais besoin d'avis d'experts...

    Voici le 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
     
    #include "stdafx.h"
    #include "stdlib.h"
    #include "string.h"
     
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    	char mot[51];
    	char *pmotPlusLg;
    	int lgmotPlusLg, lgMotLu, cpt=0;
     
    	lgmotPlusLg=-1;
    	pmotPlusLg = " ";
     
    	//Prototypes
    	void FONCTION(char *, int *, int *, char [], int);
     
    	printf("\tLecture d'une suite de mots. \nArret a la lecture d'une * en 1er caractere.\n\nVeuillez entrer le mot : ");
    	gets(mot);
    	do
    	{
    		if((strcmp(mot, pmotPlusLg))==0)
    			cpt++;
    		else
    		{
    			lgMotLu=strlen(mot);
    			if(lgMotLu>lgmotPlusLg)
    				FONCTION(pmotPlusLg, &cpt, &lgmotPlusLg, mot, lgMotLu);
    			else
    			{
    				if(lgMotLu==lgmotPlusLg)
    				{
    					if((strcmp(mot, pmotPlusLg))<0)
    						FONCTION(pmotPlusLg, &cpt, &lgmotPlusLg, mot, lgMotLu);
    				}
    			}
    		}
    		printf("Veuillez rentrer le nouveau mot : ");
    		gets(mot);
    	}
    	while(mot[0]!='*');
    	free(pmotPlusLg);
    	printf("Le mot le plus long est : %s avec une longueur de : %d. Il a ete lu %d fois\n", pmotPlusLg, lgmotPlusLg, cpt);
     
    	system("PAUSE");
     
    	return 0;
    }
     
    //Fonction
     
    void FONCTION(char *i, int *c, int *lgi, char mLu[], int lgmLu)
    {
    	free(i);
    	*c=1;
    	i=(char *) malloc(lgmLu + 1);
    	strcpy(i, mLu);
    	*lgi=lgmLu;
    }
    Merci d'avance.

  2. #2
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    T'abuses, on te donnes des conseils pourquoi?
    [URL="http://www.developpez.net/forums/showpost.php?p=2681855&postcount=4"]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    test2.c:1:20: erreur: stdafx.h : Aucun fichier ou répertoire de ce type
    test2.c:5: erreur: expected declaration specifiers or «..." before «_TCHAR"
    test2.c:6: attention : no previous prototype for «_tmain"
    test2.c: In function «_tmain":
    test2.c:12: attention : assignment discards qualifiers from pointer target type
    test2.c:15: attention : nested extern declaration of «FONCTION"
    test2.c:17: erreur: implicit declaration of function «printf"
    test2.c:17: attention : incompatible implicit declaration of built-in function «printf"
    test2.c:18: erreur: implicit declaration of function «gets"
    test2.c:18: attention : nested extern declaration of «gets"
    test2.c: Hors de toute fonction :
    test2.c:52: attention : no previous prototype for «FONCTION"
    test2.c: In function «FONCTION":
    test2.c:55: attention : passing argument 1 of «malloc" as unsigned due to prototype

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 25
    Points : 7
    Points
    7
    Par défaut
    Je ne pense pas que ce soit un problème de gets mais bon...

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 25
    Points : 7
    Points
    7
    Par défaut
    Avec fgets le résultat est le même !

  5. #5
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Âge : 56

    Informations forums :
    Inscription : Avril 2007
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Tu peux t'arranger pour que ton code apparaisse indenté? Cela facilite la lecture donc la compréhension...

    Il y a des balises pour inclure du code.

    David.
    --

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 52
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    On retrouve les mêmes erreurs de post en post.
    Comme le suggère ton titre, il y a bien un problème d'allocation dynamique.

    Ta variable pmotPlusLg est déclarée comme un pointeur de caractère.
    Avant de t'en servir, il faut lui allouer de la mémoire (Malloc) ou la faire pointer sur une chaîne valide.

    Ensuite ton pointeur non initialisé est passé en paramètre à une fonction qui le libère --> ????.

    Pour finir, si tu veut comparer la longueur des mots, utilise donc strlen().

    strcmp sert a comparer alphabétiquement des chaînes ainsi strcmp("BB","AAAAAA") retourne 1,
    ce qui n'est sûrement pas le résultat que tu espérais.

    Bon courage et pense aux balises codes.

  7. #7
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void FONCTION(char *i, int *c, int *lgi, char mLu[], int lgmLu)
    {
    	free(i);  // au départ, *i n'a pas été alloué de façon dynamique:
                      // main ->  char *pmotPlusLg; ... pmotPlusLg = " ";
    	*c=1;
    	i=(char *) malloc(lgmLu + 1);
    	// i est une variable locale. 
            // Au retour de la fonction, l'argument correspondant (main -> pmotPlusLg) 
            // ne sera pas modifié et la mémoire allouée est perdue pour la science
                  strcpy(i, mLu);
    	*lgi=lgmLu;
    }

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 25
    Points : 7
    Points
    7
    Par défaut
    Donc il faut que j'alloue i de façon dynamique au début de la fonction puis que je le libère a la fin de la fonction et enfin que je libère pmotPlusLg en dehors de la fonction ?

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 25
    Points : 7
    Points
    7
    Par défaut
    " // i est une variable locale.
    // Au retour de la fonction, l'argument correspondant (main -> pmotPlusLg)
    // ne sera pas modifié et la mémoire allouée est perdue pour la science "

    Oui mais comment faire alors pour modifier pMotPlusLg dans la fonction (lui allouer de la mémoire, le libérer) ?

  10. #10
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    mais comment faire alors pour modifier pMotPlusLg dans la fonction (lui allouer de la mémoire, le libérer) ?
    Comme toujours :
    - utiliser la valeur de retour de la fonction
    - ou passer l'adresse de la variable à modifier et non la variable elle-même.
    Par exemple :
    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
    char * FONCTION(char *i, int *c, int *lgi, char mLu[], int lgmLu)
    {
                free(i);  // au départ, *i n'a pas été alloué de façon dynamique:
                      // main ->  char *pmotPlusLg; ... pmotPlusLg = " ";
                *c=1;
                 i= malloc(lgmLu + 1);
                 if(i != NULL)
                 {
                    strcpy(i, mLu);
                    *lgi=lgmLu;
                 }
                 return i;
    }
    .....
    pmotPlusLg = FONCTION(pmotPlusLg, &cpt, &lgmotPlusLg, mot, lgMotLu);

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 25
    Points : 7
    Points
    7
    Par défaut
    Merci le programme ne plante plus !
    Il reste juste un petit problème d'affichage.
    Exemple :

    Lecture d'une suite de mots.
    Arret a la lecture d'une * en 1er caractere.

    Veuillez entrer le mot : a
    Veuillez rentrer le nouveau mot : aa
    Veuillez rentrer le nouveau mot : bonjour
    Veuillez rentrer le nouveau mot : bonjour
    Veuillez rentrer le nouveau mot : *
    Le mot le plus long est : bonjour
    avec une longueur de : 8. Il a ete lu 2 foi
    Appuyez sur une touche pour continuer...

    Pourquoi a t-il écrit "avec une longueur..." à la ligne et apèrs un espace ???

    Voici le code modifié grâce à votre aide :

    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
     
     
    #include "stdafx.h"
    #include "stdlib.h"
    #include "string.h"
     
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    	char mot[51];
    	char *pmotPlusLg;
    	int lgmotPlusLg, lgMotLu, cpt=0;
     
    	lgmotPlusLg=-1;
    	pmotPlusLg = "";
    	pmotPlusLg = (char *) malloc(1);
     
    	//Prototypes
    	char * FONCTION(char *, int *, int *, char [], int);
     
    	printf("\tLecture d'une suite de mots. \nArret a la lecture d'une * en 1er caractere.\n\nVeuillez entrer le mot : ");
    	fgets(mot, sizeof mot, stdin);
    	do
    	{
    		if((strcmp(mot, pmotPlusLg))==0)
    			cpt++;
    		else
    		{
    			lgMotLu=strlen(mot);
    			if(lgMotLu>lgmotPlusLg)
    			{
    				pmotPlusLg=FONCTION(pmotPlusLg, &cpt, &lgmotPlusLg, mot, lgMotLu);
    			}
    			else
    			{
    				if(lgMotLu==lgmotPlusLg)
    				{
    					if((strcmp(mot, pmotPlusLg))<0)
    					{
    						pmotPlusLg=FONCTION(pmotPlusLg, &cpt, &lgmotPlusLg, mot, lgMotLu);
    					}
    				}
    			}
    		}
    		//printf("Mot le + long : %s lu %d fois\n", pmotPlusLg, cpt);
    		printf("Veuillez rentrer le nouveau mot : ");
    		fgets(mot, sizeof mot, stdin);
    	}
    	while(mot[0]!='*');
    	printf("Le mot le plus long est : %s avec une longueur de : %d. Il a ete lu %d fois\n", pmotPlusLg, lgmotPlusLg, cpt);
    	free(pmotPlusLg);
    	system("PAUSE");
     
    	return 0;
    }
     
    //Fonction
     
    char * FONCTION(char *i, int *c, int *lgi, char mLu[], int lgmLu)
    {
    	free(i);
    	*c=1;
    	i=(char *) malloc(lgmLu + 1);
    	strcpy(i, mLu);
    	*lgi=lgmLu;
    	if(i != NULL)
    	{
     
    		 strcpy(i, mLu);
             *lgi=lgmLu;
    	}
        return i;
    }

  12. #12
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Pourquoi a t-il écrit "avec une longueur..." à la ligne et apèrs un espace ???
    Parce que le fgets met dans la chaîne le caractère de fin de ligne '\n'. Si c'est génant, il faut le remplacer par '\0'

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 25
    Points : 7
    Points
    7
    Par défaut
    Ca a l'air simple mais moi je ne sais pas le faire....
    gets a plein d'autres problèmes mais pas celui là

  14. #14
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Tu peux par exemple rechercher sa présence dans la chaîne par strchr qui te donnera son adresse ou NULL si il n'y est pas (dans ce dernier cas, cela signifie que le tableau était trop petit pour stocker la ligne entière).

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    recherche "fclean" sur le forum: C'est le nom d'une fonction qu'on poste régulièrement ici, justement pour le nettoyage après un fgets().

  16. #16
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    25
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 25
    Points : 7
    Points
    7
    Par défaut
    Ok merci à tous.

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

Discussions similaires

  1. problème allocation dynamique dans C++
    Par mido1951 dans le forum C++
    Réponses: 16
    Dernier message: 23/04/2013, 21h38
  2. problème allocation dynamique tableau 2d
    Par virtual_bug dans le forum C++
    Réponses: 16
    Dernier message: 17/04/2012, 11h21
  3. Réponses: 4
    Dernier message: 06/05/2008, 13h12
  4. problème allocation dynamique
    Par josef24 dans le forum Débuter
    Réponses: 6
    Dernier message: 12/11/2007, 12h31
  5. Question sur les problèmes d'allocation dynamique
    Par slylafone dans le forum C++
    Réponses: 23
    Dernier message: 25/10/2004, 14h18

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