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 :

strcpy écrase les précédents résultats stocké dans une autre variable


Sujet :

C

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 83
    Points : 68
    Points
    68
    Par défaut strcpy écrase les précédents résultats stocké dans une autre variable
    Bonjour,

    Pour un de mes programmes, j'ai besoin de passer par une variable temporaire avant de pouvoir la stocker dans l'un des maillons d'une liste chainé. Pour réinitialiser ma variable temporaire j'utilise strcpy.

    Le soucis et que lorsque j'utilise strcpy, mes précédente "sauvegarde" au sein de ma liste chainé sont aussi réinitialisé. Comment puis je faire pour pouvoir travailler avec une seul variable et la réinitialiser sans toucher au précédente insertion ?

    Vous pouvez constater mon soucis sur la ligne 51

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    typedef struct s_list_chain{
        char* value;
        struct  s_list_chain* next;
    }linkedList;
     
    linkedList* linkedList_new(char* value){
        linkedList* node = (linkedList*) malloc (sizeof (linkedList));
        node->value = value; 
        node->next = NULL;
        return node;
    }
     
    linkedList* linkedList_add(linkedList* list, char* value){
        linkedList *newlist = linkedList_new(value);
        if (!list)
            return newlist;
     
        linkedList* head = list;
     
        while (list->next)
            list= list->next;    
        list->next=newlist;
        return head;
    }
     
    void linkedList_display(linkedList* list){
        while (list->next){
            printf("%s ", list->value);
            list = list->next;
        }
        printf("%s ", list->value);
    }
     
    int main()
    {
    	char temp [256];
    	strcpy(temp, "insertion 1");
     
    	linkedList* listeChamps = NULL;
    	listeChamps = linkedList_add(listeChamps, temp);
     
    	strcpy(temp, "insertion 2");
    	listeChamps = linkedList_add(listeChamps, temp);
     
    	linkedList_display(listeChamps); 
    	// Affiche : "insertion 2 insertion 2" et non pas "insertion 1 insertion 2"
    	system("PAUSE");
    }

  2. #2
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Hoe,

    Suis bien ton code manuellement, et tu trouveras l'erreur.

    Le fait que l'ancienne valeur soit écrasée t'oriente déjà vers la solution.
    Si les cons volaient, il ferait nuit à midi.

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 83
    Points : 68
    Points
    68
    Par défaut
    Je sais déjà d’où vient l'erreur mais a mon niveau de connaissance je ne vois pas comment la résoudre. Le soucis vient vraiment du strcpy, car je ne dois pas comprendre sa mécanique

    Quand je fais ceci dans mon main, la 2eme valeur n'est pas écrasé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	linkedList* listeChamps = NULL;
    	listeChamps = linkedList_add(listeChamps, "a");
    	listeChamps = linkedList_add(listeChamps, "b");
    	linkedList_display(listeChamps);
    Comment dois je procéder pour pouvoir stocker ce que je veux dans une variable temporaire avant de l ajouter a ma list ?

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Arnau6 Voir le message
    Le soucis vient vraiment du strcpy, car je ne dois pas comprendre sa mécanique
    Salut
    Ton souci ne vient pas de strcpy() car tu t'en sers parfaitement bien. Le souci est beaucoup plus profond et provient de linkedList_new().

    Je t'explique: tu passes à ta fonction linkedList_add() la variable "temp" qui n'est en fait qu'une adresse (on va dire 0x0a). A cette adresse 0x0a tu as stocké la chaine "Insertion 1". Donc cette valeur 0x0a transite dans linkedList_add() pour être retransmise à linkedList_New(). Et là, la fonction stocke benoîtement cette valeur (toujours 0x0a) dans le noeud.

    Ensuite tu copies "Insertion 2" dans la même variable temp (donc à l'adresse 0x0a). Et de nouveau cette adresse 0x0a va dans LinkedList_New() pour être recopiée dans le second noeud.

    Résultat: tes deux noeuds contiennent non pas une chaine mais simplement 0x0a. Et qu'y a-t-il à cette adresse ? "Insertion 2". Tu peux d'ailleurs rajouter simplement strcpy(temp, "coucou") et afficher ta liste, tu auras alors "coucou coucou".

    Si tu veux que ta liste stocke des chaines, il te faut les recopier (via strcpy()) dans tes noeuds.
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    typedef struct s_list_chain{
        char value[256];
        struct  s_list_chain* next;
    }linkedList;
     
    linkedList* linkedList_new(char* value){
        linkedList* node = (linkedList*) malloc (sizeof (linkedList));
        strcpy(node->value, value); 
        node->next = NULL;
        return node;
    }
    Et là, ça devrait fonctionner (enfin théoriquement parce que je n'ai pas testé mais je suis sûr de moi)...

    Citation Envoyé par Arnau6 Voir le message
    Quand je fais ceci dans mon main, la 2eme valeur n'est pas écrasé.
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    linkedList* listeChamps = NULL;
    listeChamps = linkedList_add(listeChamps, "a");
    listeChamps = linkedList_add(listeChamps, "b");
    linkedList_display(listeChamps);
    Oui parce que dans ce cas précis tu stockes dans tes noeuds deux adresses différentes (l'adresse qui contient "a" et celle qui contient "b") ce qui n'est plus tout à fait la même chose...
    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 du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 83
    Points : 68
    Points
    68
    Par défaut
    Merci pour ta réponse et tes explications. Cependant en appliquant ta correction, mon programme plante lors de la création du second maillon (insertion 2), a la 1er ligne de la fonction linkedList_add.

    Pour corriger toute les erreurs je dois aussi changer le type de de la variable "char* value" de la structure linkedList en "char value [256]". Pourriez vous m'indiquer pourquoi sans cette modification, mon programme plante sur le 2eme maillon

  6. #6
    Membre régulier
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2013
    Messages : 42
    Points : 80
    Points
    80
    Par défaut non
    Appelle en premier lieu la fonction linkedList_new() dans le main() , avant d appeler linkedList_add(), ca devrai marcher(??!!). Sinon pour etre plus pointilleux , Il faut toujours traiter le premier ajout delicatement .


    Apres , elle est où la fonction pour supprimer la liste (Il faut aussi traiter la suppression du premier ajout delicatement) ?

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    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 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Arnau6 Voir le message
    Merci pour ta réponse et tes explications. Cependant en appliquant ta correction, mon programme plante lors de la création du second maillon (insertion 2), a la 1er ligne de la fonction linkedList_add.

    Pour corriger toute les erreurs je dois aussi changer le type de de la variable "char* value" de la structure linkedList en "char value [256]". Pourriez vous m'indiquer pourquoi sans cette modification, mon programme plante sur le 2eme maillon
    Tu remarqueras que dans ma correction, j'avais déjà pensé à ce détail.
    Ta structure originelle n'est prévue que pour le stockage d'une simple adresse et non pas d'une chaine. Or une chaine, bien que manipulable par une simple adresse, c'est quand-même plusieurs octets et il faut donc un espace pour les stocker.

    Accessoirement, stocker une chaine dans un simple pointeur sans avoir réservé d'espace suffisant produit un comportement indéterminé ce qui est la pire des choses qui puisse t'arriver. Parce qu'un comportement indéterminé est (comme son nom l'indique), totalement imprévisible. C'est à dire que ton programme peut planter comme ne pas planter. Il peut planter dès la première insertion, dès la 2°, ou dès la 15°. Ou ne pas planter puis un jour tu rajoutes un printf() et là il plante. Et là tu t'arraches les cheveux à comprendre pourquoi le printf() fait planter.
    Donc quand (par chance) ça plante immédiatement, tu as au-moins la possibilité de comprendre la cause et y remédier...
    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
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Mei,
    Citation Envoyé par Sve@r Voir le message
    Ou ne pas planter puis un jour tu rajoutes un printf() et là il plante.
    Ou le jour où tu fais une démo !
    Si les cons volaient, il ferait nuit à midi.

Discussions similaires

  1. Ajout d'une requête SELECT d'un stock dans une autre requête.
    Par Heytabernak dans le forum Langage SQL
    Réponses: 2
    Dernier message: 07/11/2008, 09h43
  2. Réponses: 1
    Dernier message: 16/10/2008, 11h40
  3. Traiter une procédure stocké dans une autre
    Par tribaleur dans le forum Langage SQL
    Réponses: 8
    Dernier message: 22/07/2008, 20h07
  4. Réponses: 3
    Dernier message: 02/02/2007, 14h30
  5. Réponses: 3
    Dernier message: 16/01/2007, 01h28

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