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 :

Conflit d'adresse entre deux tableaux


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur calcul
    Inscrit en
    Avril 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur calcul
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2011
    Messages : 36
    Par défaut Conflit d'adresse entre deux tableaux
    Bonjour,

    Lors de l'exécution de mon programme, les valeurs d'un de mes tableaux sont modifiées involontairement au moment où les valeurs d'un autre tableau sont modifiées.

    Lorsque j'affiche les adresses des éléments de ces deux tableaux, je m'aperçois que plusieurs d'entre elles sont identiques. D'où le conflit.

    Le premier tableau est défini dans mon main.c ainsi:

    Le second tableau appartient à la structure suivante déclarée dans un .h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct elements_ {
      INT    *  numelt;            
     
      INT    *  pconnect;          /* liste des pointeurs sur la connectivite des 
                                      elements dans 'connectivite' 
     
    }ELEMENTS;
    Si j'affiche les adresses de ces deux tableaux avec les lignes suivantes:

    NB: "p1" est un pointeur qui a pris pour valeur "elements.pconnect"
    "nb_elt" est la dimension de pconnect

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	for (i=0;i<nb_elt+1;i++){
    	printf("p1[%d] = %d \t à l'adresse %d \n",i,p1[i],&p1[i]);
    	}
    et,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	for(i=0;i<14;i++)printf("&caraelemress[%d] = %f\t à l'adresse %d \n",i,caraelemress[i],&(caraelemress[i]));
    je récupère dans mon terminal respectivement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    p1[0] = 1 	 à l'adresse 235837680 
    p1[1] = 9 	 à l'adresse 235837684 
    p1[2] = 17 	 à l'adresse 235837688 
    p1[3] = 19 	 à l'adresse 235837692 
    p1[4] = 21 	 à l'adresse 235837696 
    p1[5] = 23 	 à l'adresse 235837700 
    p1[6] = 25 	 à l'adresse 235837704
    et,
    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
     
    &caraelemress[0] = 210000.000000	 à l'adresse 235837632 
    &caraelemress[1] = 0.000000	 à l'adresse 235837640 
    &caraelemress[2] = 0.000000	 à l'adresse 235837648 
    &caraelemress[3] = 0.000000	 à l'adresse 235837656 
    &caraelemress[4] = 0.000000	 à l'adresse 235837664 
    &caraelemress[5] = 0.000000	 à l'adresse 235837672 
    &caraelemress[6] = 0.000000	 à l'adresse 235837680 
    &caraelemress[7] = 0.000000	 à l'adresse 235837688 
    &caraelemress[8] = 0.000000	 à l'adresse 235837696 
    &caraelemress[9] = 0.000000	 à l'adresse 235837704 
    &caraelemress[10] = 0.000000	 à l'adresse 235837712 
    &caraelemress[11] = 0.000000	 à l'adresse 235837720 
    &caraelemress[12] = 0.000000	 à l'adresse 235837728 
    &caraelemress[13] = 0.000000	 à l'adresse 235837736
    Entre autres, p1[2] et caraelemress[7] ont la même adresse.

    Avez-vous une idée d'où cette erreur peut venir ?

    Merci d'avance

    Anthony

  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
    Dans ce que tu montres, il n'y a pas de tableaux : caraelemress et le champ pconnect ne sont pas des tableaux mais des pointeurs.

    Il serait plus simple de montrer le code incriminé, notamment celui de la création de ces tableaux.

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur calcul
    Inscrit en
    Avril 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur calcul
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2011
    Messages : 36
    Par défaut
    Voici les lignes de code qui créent l'espace mémoire pour la structure "elements"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /* allocation de l'espace
         des elements
         ---------------------- */
      if ( Alloc_elements(&elements) )
      {
              dammsg(ERR_PILE_,routine);
              return(-1);
      }
    La fonction Alloc_elements appelée est la suivante: (Dans mon message précédent, j'avais retiré plusieurs champs dans la déclaration de la 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
    15
    16
    17
    18
    19
    20
    21
     
    INT Alloc_elements(struct elements_ * var){
      register INT code_erreur = 0 ;
     
      if( ((var->numelt=integer_alloc(var->numelt,nb_elt))==(INT*)(NULL)) ||
      ((var->propnumtyp=integer_alloc(var->propnumtyp,nb_elt))==(INT*)(NULL)) ||
      ((var->formelts=integer_alloc(var->formelts,nb_elvol))==(INT*)(NULL)) ||
      ((var->repelt=integer_alloc(var->repelt,2*nb_elvol))==(INT*)(NULL)) ||
      ((var->pconnect=integer_alloc(var->pconnect,nb_elt+1))==(INT*)(NULL)) ||
      ((var->numstr=integer_alloc(var->numstr,nb_elvol))==(INT*)(NULL)) ||
      ((var->codelt=integer_alloc(var->codelt,nb_elt))==(INT*)(NULL)) ||
      ((var->repcorota0=Real_alloc(var->repcorota0 ,9*nb_elpou))==(REEL*)(NULL)) ||
      ((var->coordlocini=Real_alloc(var->coordlocini,nb_elpou))==(REEL*)(NULL)) ||
      ((var->connectneuels=integer_alloc(var->connectneuels,mx_connec))==(INT*)(NULL)) )
      {
          dammsg(ERR_ALLOCMEM_,"struct elements_","Alloc_elements");
          code_erreur=1;
      }
     
      return code_erreur;
    }
    La fonction Real_alloc est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    REEL * Real_alloc(REEL * var, const INT nElements) {
      register INT i;
      if (nElements < 0) return((REEL *)(NULL));
      if ((var=NEW_DIM(var,nElements,REEL))==(REEL *)NULL) return((REEL *)(NULL));
      for (i = 0; i<nElements; i++) var[i] = c__zero;
      return var;
    }

    et Integer_alloc:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    INT * integer_alloc(INT * var, const INT nElements) {
      INT i;
      if (nElements < 0) {
        return (INT *)(NULL);
      }
    Et l'espace mémoire pour caraelemress est alloué ici:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      if ((caraelemress=(REEL *)Real_alloc((REEL *)NULL,indref))==((REEL *)NULL))
      {
         dammsg(ERR_ALLOCMEM_,"caraelemress",routine);
         return(-1);
      }

    Ca fait beaucoup de code d'un coup ! Merci pour ton aide.

  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur calcul
    Inscrit en
    Avril 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur calcul
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2011
    Messages : 36
    Par défaut
    Pour info supplémentaire, c'est entre les lignes 20 et 36 de la fonction suivante (lorsque je manipule les valeurs du tableau pointé par caraelemress), que les valeurs du tableau pointé par pconnect de ma structure elements sont involontairement modifiées.

    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
     
    void caraelemressort(REEL *cararess, REEL *caraelemress)
    {printf("------------ ENTRE DANS CARAELEMRESSORT ---------\n");
     
     /*variables locales*/
       register INT i;
       register REEL v,E,G,A,J,Iy,Iz;
       REEL *p;
     
     
     
    	  printf("adresses des éléments de la matrice de rigidité \n");
     
     
    	for(i=0;i<14;i++)printf("&caraelemress[%d] = %f\t à l'adresse %d \n",i,caraelemress[i],&(caraelemress[i]));
     
     
     
       /* terme E.A */
       caraelemress[2]=E*A;
     
       /* terme G.J */
       caraelemress[3]=G*J;
     
       affiche_table_elem();
       /* terme 2*E.Iy */
       v=c__deux*E*Iy;
       caraelemress[4]=v;
       v*=c__deux;
       caraelemress[6]=v;
     
       /* terme 2*E.Iz */
       v=c__deux*E*Iz;
       caraelemress[5]=v;
       v*=c__deux;
       caraelemress[7]=v;
       affiche_table_elem();
     
        p=&caraelemress[2];
       for(i=6;i<14;i++) p[i]=cararess[i]; 
    	for(i=0;i<14;i++)printf("caraelemress[%d] = %f \n",i,caraelemress[i]);
    	for(i=0;i<14;i++)printf("cararess[%d] = %f \n",i,cararess[i]);
    printf("------------ SORTIE DE CARAELEMRESSORT ---------\n");
    }

  5. #5
    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
    Le code qui dit créer de l'espace mémoire pour les elements : if ( Alloc_elements(&elements) ) : ne crée pas de structure elements_. celle-ci doit déjà pré-exister et même ses champs doivent avoir été initialisés par quelque chose puisqu'ils sont en arguments des integer_alloc() et Real_alloc() dans Alloc_elements().

    Si on regarde Real_alloc() (je suppose que integer_alloc() fonctionne pareillement, mais son code est incomplet), on peut penser que NEW_DIM() est une macro (à cause de l'argument REEL) qui alloue ou plutôt réalloue dynamiquement (puisque var est en argument, sinon à quoi servirait-il ?), mais alors on est surpris par la remise à zéro de la ligne 6 qui suit.

    Bref, il manque des informations à préciser, car là c'est un peu un jeu de devinettes. Au minimum :
    - la macro NEW_DIM()
    - le code de création et initialisation de la structure struct elements_ en argument de Alloc_elements()

    Sinon, beaucoup de cast inutiles (inutile de caster NULL) qui alourdissent le code. La présence de cast montre souvent une mauvaise maîtrise du code.

  6. #6
    Membre averti
    Homme Profil pro
    Ingénieur calcul
    Inscrit en
    Avril 2011
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur calcul
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2011
    Messages : 36
    Par défaut
    Voici la fonction integer_alloc complète (désolé pour cet oubli):

    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
     
    INT * integer_alloc(INT * var, const INT nElements) {
      INT i;
      if (nElements < 0) {
        return (INT *)(NULL);
      }
     
      var = (INT *)( (var!=(INT *)(NULL)) ? 
            realloc((void *)var, nElements*SIZINT_) :
            calloc(nElements, SIZINT_));
     
      if (var != (INT *)(NULL)) {
    	printf("\t initialisation \n");
        for (i = 0; i<nElements; i++) {
    	var[i] = 0;   /* initialisation a 0 */
    	}
      }
      return (INT *)var;
    }
    Concernant le rôle de var, voici ce commentaire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    /* 
       FONCTIONS GENERALES D'ALLOCATION : 
          parametres - var       : pointeur sur le tableau a allouer
                     - nElements : nombre d'elements
          retournent un pointeur (=NULL en cas d'echec) sur la variable a allouer
    */

    NEW_DIM est en effet une macro:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #define NEW_DIM(var, n, type) ( (var) = (type *)((var) ? \
                            realloc((char *)(var), (unsigned)(n)*sizeof(type)) : \
                            calloc((unsigned)(n), sizeof(type))))
    En ce qui concerne la création de la structure elements, je ne vois pas d'autre code que:

    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
     
    typedef struct elements_ {
      INT    *  numelt;            /* tableau de numerotation des elements
                                      (dim = nb_elt) */
      INT    *  propnumtyp;        /* liste des
                                      numeros de prop num des elements volumiques 
                                      numeros de prop pou des elements poutres
    				  numero de prop ress des elements ressorts
                                      type des ddl esclaves des elements rigide
                                      fid contenant la definition des super-elements
                                      (dim = nb_elt) */
      INT    *  formelts;          /* codes des formes geometriques des elements 
                                     volumiques 
                                      (dim = nb_elvol) */
      INT    *  repelt;            /* liste des numeros (utilisateur/internes) 
                                      de reperes et de calcul de contrainte
                                      des elements volumique
                                      (dim = 2*nb_elvol) */
      INT    *  numstr;            /* liste des numeros (utilisateur/internes) de 
                                      stratification des elements volumiques
                                      (dim = nb_elvol) */
      INT    *  codelt;            /* liste des codes interne des elements
                                      (dim = nb_elt) */
     
      INT    *  pconnect;          /* liste des pointeurs sur la connectivite des 
                                      elements dans 'connectivite' 
                                      (dim = nb_elt+1)*/
      INT    *  connectneuels;     /* liste (utilisateur/internes) des 
                                      connectivites des elements
                                      (dim = mx_connec) */
      REEL   *  repcorota0;        /* tableau des matrices de rotation initial du
                                      repere corotationel de l'element 
                                      (dim= 9 * nb_elpou ) */ 
      REEL   *  coordlocini;       /* tableau des coordonees variables initials de
                                      l'element dans sont repere corotationel
                                       (dim= nb_elpou ) */ 
    }ELEMENTS;

    Je crois que cette partie de code doit permettre de passer chacun des champs de cette structure dans des fonctions telles que Integer_alloc ou Real_alloc.

    Je suis conscient que je ne fais que lancer des morceaux de code et des commentaires de code dont je ne saisi pas à 100% les rôles. Je continue de parcourir ton dernier post pour apporter des précisions sur mon problème. En espérant que celles puisse t'aider à le résoudre. Merci pour cette aide.

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

Discussions similaires

  1. recherche entre deux tableaux
    Par jaarod dans le forum Excel
    Réponses: 4
    Dernier message: 21/10/2008, 10h05
  2. Tansfert d'adresse entre deux comptes
    Par superjeanpi dans le forum Outlook Express / Windows Mail
    Réponses: 3
    Dernier message: 23/09/2007, 01h08
  3. [c#2] affectation entre deux tableaux en c#
    Par mstic dans le forum C#
    Réponses: 4
    Dernier message: 16/07/2007, 10h44
  4. [Débutant] Test d'équivalence entre deux tableaux ?
    Par kmikase dans le forum Fortran
    Réponses: 5
    Dernier message: 13/01/2007, 16h53
  5. [VBA-E]:copier entre deux tableaux sur deux classeurs
    Par VBBBA dans le forum Macros et VBA Excel
    Réponses: 39
    Dernier message: 28/06/2006, 15h39

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