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 :

Erreur liée aux pointeurs


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 42
    Par défaut Erreur liée aux pointeurs
    Bonsoir,

    je patauge depuis hier avec ce code qui est destinné à tourner sur un microcontrolleur. Et je ne suis pas sûr si cela est une erreur de codification (fortement probable compte tenu des difficultés que j'ai avec les pointeurs et les tableaux :o ) ou un problème d'environnement de développement (MPLAB IDE de microchip). Voici le code en question :

    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
        #include <iostream>
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        using namespace std;
        typedef struct {
            char *Rx_buffer; // RX buffer
        } RS_232;
        RS_232 Polarimetre;
        char UART5_Buffer_Rx[32];
     
     
    unsigned char MesurerRotation(char * cBuffer) {
     
        char tem[15] = "je suis labas";
        char *jj;
        char i;
     
        Polarimetre.Rx_buffer = &UART5_Buffer_Rx[0];
        jj = &UART5_Buffer_Rx[0];;
     
        for (i = 0; i < 15; i++)
            UART5_Buffer_Rx[i] = tem[i];
     
        cBuffer = Polarimetre.Rx_buffer;
        cBuffer = &UART5_Buffer_Rx[0];
        cBuffer = jj;
     
        return 1;
    }
     
        int
        main(void) {
            char Reponse[20] = {0};
            char *Rep2;
            unsigned char I;
            I = MesurerRotation(&Reponse[0]);
         I = MesurerRotation(Rep2);
            return 0;
        }

    Exécuté avec code blocks, je n'ai pas de problème jusqu'à la fin de la fonction MesurerRotation(&Reponse[0]); où la variable cBuffer pointe bien vers UART5_Buffer_Rx[0].

    Mais lors du retour dans le main(), la valeur du pointeur est perdue. Et ceci de la même façon pour le deuxième appelle (ce qui est assez logique).

    mais je ne comprends pas ce qui cloche... c'est probablement ce qui explique le comportement de la fonction MesurerRotation lorsque je l’exécute avec MPLAB : cBuffer ne change pas de valeur lors de l’exécution des lignes

    cBuffer = Polarimetre.Rx_buffer;
    cBuffer = &UART5_Buffer_Rx[0];
    cBuffer = jj;


    Bref, je deviens vert, rouge....

    Toute aide sera plus que la bien venue !
    Jean-Marie

  2. #2
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    cBuffer = Polarimetre.Rx_buffer;
    cBuffer = &UART5_Buffer_Rx[0];
    cBuffer = jj;
    Où sont ces lignes dans le code ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 42
    Par défaut
    Oups !

    J'ai du faire un coupé au lieu de coller. J'ai corrigé le code !

    Jean-Marie

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Mais mais ?? Où est allouée la mémoire associée à ces pointeurs sur char ??

    Pardon mais ce code ne me semble avoir ni queue ni tête (ou alors ma bronchite et mon manque de sommeil sont plus forts que prévus).

    C'est quoi cette fonction qui prend un paramètre et l'affecte à une variable globale, puis à une autre variable globale, puis a une variable locale non initialisée avec la valeur de cette précédente variable globale ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        cBuffer = Polarimetre.Rx_buffer;
        cBuffer = &UART5_Buffer_Rx[0];
        cBuffer = jj;
    Si c'est un code de test, il ne teste pas grand chose ou alors je n'ai pas compris quoi...

    Petite remarque une fonction (autre que main) qui retourne en dur la valeur 1 devrait avoir un retour de type void, sauf pour assurer une compatibilité de prototype avec d'autres fonctions. Ce n'est visiblement pas le cas de MesurerRotation().

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 42
    Par défaut
    Citation Envoyé par Bktero Voir le message
    C'est quoi cette fonction qui prend un paramètre et l'affecte à une variable globale, puis à une autre variable globale, puis a une variable locale non initialisée avec la valeur de cette précédente variable globale ?
    Si c'est un code de test, il ne teste pas grand chose ou alors je n'ai pas compris quoi...
    Tu n'as pas tout à fait tord, c'est un empilement quelque peu curieux qui n'est pas lié à mon programme. Il s'agit juste d'un teste : je recherche le problème que je rencontre : je ne récupère pas dans ma fonction la valeur que je veux transmettre.
    Comme j'ai un empilement un peu compliqué de variable et encore plus de problème avec les pointeurs j'ai "bâti" ce teste.

    Le contexte :
    j'ai plusieurs appareils munis d'une connexion RS232 qui communiquent avec un microcontrolleur.

    J'ai créé une structure qui me permet de gérer l'état des périphériques du microcontrolleur, dont un pointeur qui est pointe sur un tableau. Ce tableau récupère les données qui arrivent sur le périphérique (géré par interruption). Puis au court de l'exécution du programme j'utilise le nom de l'appareil pour récupérer les données dont j'ai besoin à ce moment là.

    C'est probablement un peu tara busqué comme démarche, mais je ne suis pas un pro (la meilleur preuve étant ma faible maitrise des pointeurs)

    Petite remarque une fonction (autre que main) qui retourne en dur la valeur 1 devrait avoir un retour de type void, sauf pour assurer une compatibilité de prototype avec d'autres fonctions. Ce n'est visiblement pas le cas de MesurerRotation().
    Ce return,dans ce cas n'a pas d'utilité. Mais mes fonctions retournent l'état des machines, d'où ce return resté ici.

    Jean-Marie

  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
    Je n'arrive pas à comprendre ce que tu veux faire même et surtout en lisant ton 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
    unsigned char MesurerRotation(char * cBuffer)   // cBuffer est une variable locale initialisée lors de l'appel
    {
        char tem[15] = "je suis labas";
        char *jj;
        char i;
     
        Polarimetre.Rx_buffer = &UART5_Buffer_Rx[0]; // donc Polarimetre.Rx_buffer == UART5_Buffer_Rx
        jj = &UART5_Buffer_Rx[0];                    // donc jj == UART5_Buffer_Rx 
     
        for (i = 0; i < 15; i++)                    // Remplissage du tableau global
            UART5_Buffer_Rx[i] = tem[i]; 
     
    // On n'a pas utilisé la valeur de l'argument passé à cBuffer lors de l'appel. 
    // Donc ce ne devrait pas être un paramètre mais une variable locale ordinaire. 
        cBuffer = Polarimetre.Rx_buffer;       // donc cBuffer == UART5_Buffer_Rx
        cBuffer = &UART5_Buffer_Rx[0];         // donc cBuffer == UART5_Buffer_Rx
        cBuffer = jj;                          // donc cBuffer == UART5_Buffer_Rx
        return 1; 
    // et cBuffer est détruit. Les affectations précédentes n'ont servi à rien                
    }
    La fonction a le même effet que cette version :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    unsigned char MesurerRotation(void) 
    {
        char tem[15] = "je suis labas";
        char i;
        Polarimetre.Rx_buffer = UART5_Buffer_Rx; 
        for (i = 0; i < 15; i++)  UART5_Buffer_Rx[i] = tem[i]; 
        return 1;                
    }

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 42
    Par défaut
    Citation Envoyé par diogene Voir le message
    La fonction a le même effet que cette version :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    unsigned char MesurerRotation(void) 
    {
        char tem[15] = "je suis labas";
        char i;
        Polarimetre.Rx_buffer = UART5_Buffer_Rx; 
        for (i = 0; i < 15; i++)  UART5_Buffer_Rx[i] = tem[i]; 
        return 1;                
    }
    Vu comme cela effectivement, la variable étant globale il n'y a pas besoin de faire plus compliqué.

    Mais (et c'est là que je suis peut être un peu trop ...), cette variable est utiliser par un périférique UART, le numéro 5 dans ce cas :
    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
     
    // UART 2 interrupt handler
    // it is set at priority level 2
     
    void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void) {
        // Is this an RX interrupt?
        if (INTGetFlag(INT_U2RX)) {      
            UART2_Buffer_Rx[UART2_NbreBytes_Rx] = ReadUART2();
            // Clear the RX interrupt Flag
            INTClearFlag(INT_U2RX);
            if (UART2_Buffer_Rx[UART2_NbreBytes_Rx] == 0x0D)
                UART2_Rx_Recu = 1;
            UART2_NbreBytes_Rx++;
        }
     
    }
    Mais dans mon code je ne veux pas utiliser UART5 ainsi que l'ensemble des variables qui la concernent : car je veux travailler avec les autres périphériques de la même manière. j'ai donc créé une structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    typedef struct {
        UART_MODULE id;
        UART_LINE_CONTROL_MODE NbreBits;
        UART_LINE_CONTROL_MODE Parity;
        UART_LINE_CONTROL_MODE StopBits;
        UINT32 DataRate;
        UINT8 Initialise;
        UINT8 *Rx_buffer; // RX buffer
        UINT8 *Tx_buffer; // TX buffer
        UINT8 *Rx_NbreBytesRecu;
        UINT8 *Rx_Recieved;
        UINT8 *Tx_Recieved;
    } RS_232;
    Qui me permet une fois l'initialisation réaliser de ne plus initialiser que le nom du périphérique (polarimètre, balance, cryostat, ...).

    Puis dans le code qui assure la régulation du process je dois utiliser les valeurs stockées comme polarimetre.Rx_buffer et c'est là que j'ai besoin comme ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
                // Demande de la valeur du pouvoir rotatoire
                ReceptionData = MesurerRotation(&pReponse);
                if (ReceptionData == 1)
                {
                    ReceptionData = 0;
                    memcpy(&ReponseExtraction,pReponse[11],8);
                    ReponseExtraction[8] = 0;
                    Cristallisation.Rotation = atof(&ReponseExtraction);
                }
    La variable Cristallisation.Rotation permet de piloter le process dans une autre partie du programme.

    Voilà, j'espère avoir été un peu plus clair.
    Jean-Marie

Discussions similaires

  1. Réponses: 34
    Dernier message: 28/11/2014, 16h24
  2. Réponses: 18
    Dernier message: 28/01/2011, 21h33
  3. obtention de multiples erreurs liées aux sessions
    Par moiameme dans le forum Langage
    Réponses: 5
    Dernier message: 25/03/2008, 18h10
  4. Réponses: 4
    Dernier message: 28/10/2007, 12h07
  5. Erreur liée aux accents
    Par Mickael49 dans le forum Requêtes
    Réponses: 2
    Dernier message: 20/12/2006, 08h34

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