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 mémoire (chaines de carac)


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2013
    Messages : 30
    Par défaut problème mémoire (chaines de carac)
    Bonjour tout le monde, c'est ma première participation dans ce forum , j’espère être le bienvenu parmis vous : p .

    donc voila j'ai écrit cette fonction qui fait convertir une chaîne de nombre en une liste chaînée voila le code :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     list* fonction(char *chaine,list* liste)
     
     { char *ptr=chaine; 
     
        int car; 
     
           for(ptr;*ptr!='\0';ptr++) 
     
            liste=ajouterNumDebut(liste,car=(*ptr-48));
     
     return liste;
    }

    en main() je l'ai déclarée comme ça :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    list* nombre=init(); 
     
    char *chaineNombre=malloc(sizeof(char));
     
    //sans malloc ça marche pas je ne sais pas pq 
     
    //ensuite l'appel 
     
    nombre=fonction(chaineNombre,nombre);

    ça marche bien pour une longueur de chaîne <= 7 (1234567 par exemple) , mais avec un numéro de plus (12345678) ça plante (programme.exe a cessé de fonctionner )

    help me !!

  2. #2
    Membre Expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Par défaut
    Que contient "ajouterNumDebut" ?
    Peux-tu aussi mettre le détail de la structure "liste" ?

    (et à tout hasard : pourquoi "*ptr - 48" ?)

    Tu es conscient que dans ton main, il n'y a qu'un seul caractère d'après ton malloc ?
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2013
    Messages : 30
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct noeud
    {   int num;
        struct noeud *suivant;
    }list;

    en fait je n'ai pas bien compris pourquoi, mais quand j'enlève le malloc , ça plante dés le début !

    et pour le *ptr-48 , ça sert à stocker dans la liste le chiffre équivalent du caractère saisi.

    d'ailleurs je ne pense pas que le problème viens de la fonction ajoutnumdebut car j'ai fait des tests .

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 875
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par minosys Voir le message
    en fait je n'ai pas bien compris pourquoi, mais quand j'enlève le malloc , ça plante dés le début !
    Salut
    Tu crées un pointeur "chaineNombre" (sur quoi il pointe ? Personne ne le sait). Ensuite tu passes ce pointeur à fonction(). Laquelle va examiner chaque octet de ce pointeur pour y chercher un '\0'. Ben étant donné que personne ne sait sur quoi il pointe, comment peux-tu savoir qu'il y aura alors un '\0' dedans ???

    Sinon t'as remarqué que tu fais nombre=init() puis nombre=fonction(). En tout état de cause, tu as alors définitivement perdu la valeur renvoyée par init().

    Citation Envoyé par minosys Voir le message
    et pour le *ptr-48 , ça sert à stocker dans la liste le chiffre équivalent du caractère saisi.
    *ptr - '0' !!!

    Citation Envoyé par minosys Voir le message
    d'ailleurs je ne pense pas que le problème viens de la fonction ajoutnumdebut car j'ai fait des tests .
    Mouais. Enfin tu fais liste=ajouternumdebut(liste). C'est à dire que tu attends d'une fonction qu'elle te renvoie ce que tu lui as toi-même passé ; ce qui est conceptuellement assez bizarre...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2013
    Messages : 30
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Sinon t'as remarqué que tu fais nombre=init() puis nombre=fonction(). En tout état de cause, tu as alors définitivement perdu la valeur renvoyée par init().
    la fonction init fait pointer la liste sur NULL au debut;
    *ptr - '0' !!!
    pour moi c'est pareil .
    Mouais. Enfin tu fais liste=ajouternumdebut(liste). C'est à dire que tu attends d'une fonction qu'elle te renvoie ce que tu lui as toi-même passé ; ce qui est conceptuellement assez bizarre...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Mint* ajoutChiffreauDebut(Mint* liste,int val)
    {
    Mint* nouveau ;
    nouveau = (Mint*)malloc( sizeof( Mint ) ) ;
    if( nouveau != NULL ){
    nouveau->suivant = liste ;
    nouveau->chiffre = val ;
    }
    return nouveau ;
    }
    il n'y a rien de bizarre , j'envoie une copie de la liste par paramètre , je manipule ensuite je "return" le resultat par affectation

  6. #6
    Membre chevronné
    Avatar de vincent.mbg
    Homme Profil pro
    Développeur Python
    Inscrit en
    Décembre 2007
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Python

    Informations forums :
    Inscription : Décembre 2007
    Messages : 327
    Par défaut
    Bonjour à tous !

    Pas facille de suivre tous ça... j'imagine que ajoutChiffreAuDebut est en fait ajouterNumDebut et que list * est en fait Mint * ?

    Sinon t'as remarqué que tu fais nombre=init() puis nombre=fonction(). En tout état de cause, tu as alors définitivement perdu la valeur renvoyée par init().
    J'imagine que la valeur de init() se retrouve en fin de liste.
    Avec toutes ces hypothèses ton code complet doit ressembler à ceci:
    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
     
    #include <stdlib.h>
    #include <stdio.h>
     
    typedef struct list
    {
        int chiffre;
        struct list *suivant;
    } list;
     
     
    list* 
    init() {
        return NULL ;
    }
     
     
    list* 
    ajoutChiffreAuDebut(list* liste, int val)
    {
        list* nouveau ;
        nouveau = (list*)malloc( sizeof( list ) ) ;
        if( nouveau != NULL ){
            nouveau->suivant = liste ;
            nouveau->chiffre = val ;
        }
        return nouveau ;
    }
     
     
    list* 
    fonction(char *chaine, list* liste)
    { 
        char *ptr=chaine; 
        int car; 
     
        for( ; *ptr!='\0'; ptr++) 
            liste = ajoutChiffreAuDebut( liste, car=(*ptr - '0'));
     
     return liste;
    }
     
     
    int
    main (int argc, char *argv[])
    {
        list* nombre=init(); 
        //char *chaineNombre=malloc(sizeof(char));
        char *chaineNombre = "123456789" ;
        nombre=fonction(chaineNombre,nombre);
     
        list* node ;
        for ( node = nombre ; node ; node = node->suivant ) {
           printf("%d ", node->chiffre ) ;
        }
        printf("\n") ;
     
        return 0;
    }
    Je ne comprends pas pourquoi chaineNombre n'est pas initialisé mais si tu l'initialise ça marche.

    *ptr - '0' !!!
    C'est un peu plus claire que *ptr - 48 et surtout plus portable au cas ou ton programme doit tourner sur un système ou '0' ne vaut pas 48
    Mon guide pour apprendre Tkinter - N'oubliez pas de consulter les FAQ Python ou de visiter mon blog

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 875
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par minosys Voir le message
    pour moi c'est pareil .
    Si c'est pareil alors autant utiliser ma notation.
    Donc c'est peut-être pareil pour toi mais pas pour ceux qui te lisent (d'où la question de Metalman). Tu ne programmes pas que pour toi. Et c'est peut-être pareil aujourd'hui mais si demain on change la codification des caractères ça le sera beaucoup moins...

    Citation Envoyé par minosys Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Mint* ajoutChiffreauDebut(Mint* liste,int val)
    {
    Mint* nouveau ;
    nouveau = (Mint*)malloc( sizeof( Mint ) ) ;
    if( nouveau != NULL ){
    nouveau->suivant = liste ;
    nouveau->chiffre = val ;
    }
    return nouveau ;
    }
    il n'y a rien de bizarre , j'envoie une copie de la liste par paramètre , je manipule ensuite je "return" le resultat par affectation
    Un programme réussi ce n'est pas seulement un programme qui fonctionne. C'est aussi un programme qu'on peut comprendre et faire évoluer facilement.
    S'il faut aller voir le détail de cette fonction pour comprendre alors ta façon de l'appeler alors il n'est pas vraiment réussi. Il y a d'autres façon d'écrire cette fonction (et aussi pour la fonction init()).
    Accessoirement, as-tu réfléchi à ce qui deviendrait de ta variable "liste" si nouveau = NULL ???

    Mis à part ça, cette fonction montre que t'as pas bien compris à quoi sert une liste. Une liste s'utilise quand on veut avoir des éléments triés. On peut en effet insérer facilement un nouvel élément au milieu des autres en déplaçant juste 2 pointeurs.
    Donc quand on a un nouvel élément, on cherche où il va dans la liste puis on l'insère. Toi, tu ne cherches pas son emplacement, tu te contentes d'insérer ton nouvel élément au début. Dans ce cas, autant utiliser un simple tableau beaucoup plus maniable...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2013
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2013
    Messages : 30
    Par défaut
    merci beaucoup pour vos réponses ça me fait plaisir , en fait la raison pour laquelle je m’intéresse uniquement a l'ajout au début c'est par ce que j'utilise la liste pour représenter un nombre saisi sous forme d'une chaîne.

    maintenant je déclare la chaine et je l'initialise comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    char *chaine=(char*)malloc(500*sizeof(char));
    //ou tout simplement
     chaine=malloc(500);
    // puisque char = 1octet
    le problème c'est que je voulais déclarer une chaîne qui peut contenir autant de caractères que l'utilisateur veut saisir par clavier (sans dépassant la mémoire bien sûr ).

    excusez moi mais je suis encore débutant et je galère un peu avec l'allocation et les pointeurs.

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 875
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par minosys Voir le message
    maintenant je déclare la chaine et je l'initialise comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char *chaine=(char*)malloc(500*sizeof(char));
    //ou tout simplement
     chaine=malloc(500);
    // puisque char = 1octet
    Garde la première notation. Avec l'utf-8, un char ne fait aujourd'hui plus forcément un octet...
    Citation Envoyé par minosys Voir le message
    le problème c'est que je voulais déclarer une chaîne qui peut contenir autant de caractères que l'utilisateur veut saisir par clavier (sans dépassant la mémoire bien sûr ).
    Tu as alors 2 façons de faire
    1. tu décides qu'il ne pourra pas saisir plus de 500 caractères et tu utilises fgets(chaine, 500, stdin). Déjà petit bémol il y en aura au maximum 499 car la fonction garde une place pour le '\0'. Sinon donc l'avantage c'est que l'utilisateur ne dépasse pas la taille de la zone. L'inconvénient c'est que s'il saisit plus de 500 car, l'excédent reste dans stdin et il faut alors réfléchir de ce que l'on en fait.
    2. tu décides que l'utilisateur peut saisir autant qu'il veut. Dans ce cas il te faut programmer un peu différemment et faire de cette façon
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      char *chaine=NULL;
      int lg=0;
      getline(&chaine, &lg, stdin);
      Cette fonction va allouer elle-même via malloc ce qu'il faut pour stocker la saisie. Et elle stockera dans lg la taille allouée. Dans ce cas, comme les 2 variables vont ensemble, vaut alors mieux les grouper dans une structure.
      getline() est une fonction relativement récente. Je crois qu'on peut trouver sur ce forum un TP où on la refait...


    Citation Envoyé par minosys Voir le message
    excusez moi mais je suis encore débutant et je galère un peu avec l'allocation et les pointeurs.
    Oui, comme tous les débutants. Mais tu t'en sors pas mal...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. [CR9] [VB.NET] problème mémoire
    Par prophetky dans le forum SDK
    Réponses: 1
    Dernier message: 26/05/2005, 08h36
  2. Problème mémoire
    Par charliejo dans le forum MFC
    Réponses: 8
    Dernier message: 13/04/2005, 13h45
  3. Problème de chaine sur une page HTML
    Par Kerod dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 23/11/2004, 16h23
  4. Problémes mémoire avec le bde sur des bases paradox
    Par Keke des Iles dans le forum Bases de données
    Réponses: 2
    Dernier message: 27/05/2004, 16h55
  5. Problème mémoire avec une dll par chargement dynamique
    Par widze19 dans le forum C++Builder
    Réponses: 6
    Dernier message: 15/12/2003, 13h20

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