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 :

Modification des assignations dans un tableau 2d


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 211
    Par défaut Modification des assignations dans un tableau 2d
    Bonjour à tous,

    J'ai un tableau 2D dont la longueur de la 2ème dimension est variable

    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
    #include <stdio.h>
    #include <stdlib.h>
     
     
    int main() {
     
        long long **tableau = (long long **)malloc(10 * sizeof(long long *));
        if (tableau == NULL) {
            fprintf(stderr, "Allocation de mémoire échouée\n");
            return 1;
        }
     
        for (int i = 0; i < 10; i++) {
            tableau[i] = (long long *)malloc((i+1)* 1000 * sizeof(long long));
            if (tableau[i] == NULL) {
                fprintf(stderr, "Allocation de mémoire échouée\n");
                return 1;
            }
     
        }
     
        return 0;
    }
    Donc j'ai un tableau
    tableau[0] avec 1000 données possible
    tableau[1] avec 2000 données possible
    tableau[2] avec 3000 données possible
    ....

    Je voudrais savoir s'il était possible d'affecter les données d'une tableau (tableau source) à un autre (tableau destination )... sans pas passer les étapes realloaction de la mémoire du tableau (destination) et puis copie des données du tableau source vers le tableau.

    ou en d'autre mot que tableau[1]=tableau[2] (le fait de perde les données du tableau 1 ne pose pas de problème)

    Merci

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    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 814
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par sebaaas Voir le message
    sans passer les étapes realloaction de la mémoire du tableau (destination) et puis copie des données du tableau source vers le tableau.
    Non. L'allocation reste obligatoire (pour pouvoir copier A dans B il faut que B ait assez de place, ça me semble plutôt incontournable)

    En revanche si la seconde dimension est variable, la première, elle, ne l'est pas => malloc est alors inutile pour celle-là.
    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]

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Citation Envoyé par sebaaas Voir le message
    Je voudrais savoir s'il était possible d'affecter les données d'une tableau (tableau source) à un autre (tableau destination )... sans pas passer les étapes realloaction de la mémoire du tableau (destination) et puis copie des données du tableau source vers le tableau.

    ou en d'autre mot que tableau[1]=tableau[2] (le fait de perde les données du tableau 1 ne pose pas de problème)
    La réponse est dans la question: perdre des données EST un problème.

    Quand on appelle malloc(), on obtient un pointeur. La valeur de ce pointeur sert à 2 choses:
    1. Accéder à la région obtenue pour y lire ou écrire des données
    2. C'est aussi la valeur à conserver car c'est le nombre qu'il faudra passer à free() pour rendre la région.

    Ici tableau[1] contient le pointeur qui correspond à la réservation de 2000 long long. En faisant tableau[1]=tableau[2], tu perds l'adresse dans tableau[1] et ne pourra plus rendre la mémoire allouée, désormais les 2 pointeurs tableau[1] et tableau[2] ont la même valeur.

    Des choses possibles:
    1. Tu libères la mémoire dans tableau[1] avant de modifier tableau[1] en faisant free(tableau[1]); tableau[1]=tableau[2];, mais à la fin il faudra libérer ou bien tableau[1] ou bien tableau[2] mais pas les 2 car ils correspondent à la même région!
    2. Tu peux échanger les valeurs de tableau[1] et de tableau[2], ainsi au moment de la libération free(tableau[1]) libèrera les 3000 long long et free(tableau[2]) libèrera les 2000 long long. Mais tableau[2] change de valeur et peut-être que tu ne veux pas cela.
    3. Ou tu peux allouer les données différemment en séparant l'utilisation des tableau[i] pour accéder aux données, des tableau[i] nécessaires à la libération. 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
      16
      17
      18
      19
      20
      21
      22
      23
          long long **tableau_reserve = malloc( 10 * sizeof *tableau_reserve );
          if ( tableau_reserve == NULL ) {
              fprintf( stderr, "Allocation de mémoire échouée\n" );
              return 1;
          }
          long long **tableau = malloc( 10 * sizeof *tableau );
          if ( tableau == NULL ) {
              fprintf( stderr, "Allocation de mémoire échouée\n" );
              return 1;
          }
          for ( int i = 0 ; i < 10 ; i++ ) {
              tableau[i] = tableau_reserve[i] = malloc( (i+1) * 1000 * sizeof(*tableau[i]) ); // séparation des 2 rôles
              if ( tableau[i] == NULL ) {
                  fprintf( stderr, "Allocation de mémoire échouée\n" );
                  return 1;
              }
          }
          // ensuite on peut utiliser les tableau[i] pour accéder aux données et les réaffecter si voulus. Mais les tableau_reserve[i] ne seront utilisés que pour la libération.
          // ...
          // la libération se fait par:
          for ( int i = 0 ; i < 10 ; i++ )  free( tableau_reserve[i] );
          free( tableau_reserve );
          free( tableau ); //tout ce qui a été alloué est libéré!
    4. On peut aussi faire une unique grosse allocation, et faire que tableau et les tableau[i] pointent chacun au bon endroit dans cette allocation, les valeurs des tableau[i] peuvent être changées; à la fin, il y aura juste à libérer la grosse allocation. C'est plus concis à écrire que le code ci-dessus mais moins lisible sans faire un dessin.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 211
    Par défaut
    Citation Envoyé par dalfab Voir le message
    1. Tu libères la mémoire dans tableau[1] avant de modifier tableau[1] en faisant free(tableau[1]);, mais à la fin il faudra libérer ou bien tableau[1] ou bien tableau[2] mais pas les 2 car ils correspondent à la même région!
    C'est parfaitement ce que je voulais. Je ne savais pas que tableau[1]=tableau[2] allait résoudre mon problème.

    Grace à cette solution je n'ai besoin de allouer de la mémoire qu'au dernier tableau[x]. Cela éviter un nombre important de réallocaiton de mémoire et de copie de donnée ...

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h> 
     
    int main() {
     
    srand( time( NULL ) );
     
        int **tableau = (int **)malloc(4 * sizeof(int *));
        if (tableau == NULL) {
            fprintf(stderr, "Allocation de mémoire échouée\n");
            return 1;
        }
     
        for (int i = 0; i < 4; i++) {
            tableau[i] = (int *)malloc((i+1) * sizeof(int));
            if (tableau[i] == NULL) {
                fprintf(stderr, "Allocation de mémoire échouée\n");
                return 1;
            }
     
            for (int j=0; j < i+1; j++)
            {
                 tableau[i][j]=rand();
            }
     
        }
     
        printf("tableau[2][2] = %d\n",tableau[2][2]);
        printf("tableau[3][2] = %d\n\n",tableau[3][2]);
        free (tableau[2]);
        tableau[2]=tableau[3];
        printf("tableau[2][2] = %d\n",tableau[2][2]);
        printf("tableau[3][2] = %d\n\n",tableau[3][2]);
        tableau[3] = (int *)malloc((3+1) * sizeof(int));
         for (int i=0; i < 3+1; i++)
            {
                 tableau[3][i]=rand();
            }
             if (tableau[3] == NULL) {
                fprintf(stderr, "Allocation de mémoire échouée\n");
                return 1;
            }
        printf("tableau[2][2] = %d\n",tableau[2][2]);
        printf("tableau[3][2] = %d\n\n",tableau[3][2]);    
     
        return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    tableau[2][2] = 547658635
    tableau[3][2] = 1771015720
     
    tableau[2][2] = 1771015720
    tableau[3][2] = 1771015720
     
    tableau[2][2] = 1771015720
    tableau[3][2] = 409052761
    Merci

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    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 814
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sebaaas Voir le message
    Grace à cette solution je n'ai besoin de allouer de la mémoire qu'au dernier tableau[x]. Cela éviter un nombre important de réallocaiton de mémoire et de copie de donnée ...
    On peut même dire que les autres tableaux[y] deviennent plutôt facultatifs (si j'ai une poche pour y ranger ma monnaie je n'ai pas besoin de deux poches). Attention aussi de ne pas tester l'allocation après avoir rempli le tableau alloué (ligne 40) et, en cas de souci, de bien penser à libérer les autres pointeurs alloués avant de quitter (d'ailleurs de bien penser aussi à libérer quand le tableau est devenu inutile).
    Accessoirement, comme je l'ai déjà dit, le premier malloc() est totalement inutile.
    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]

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Des choses possibles:
    1. Tu libères la mémoire dans tableau[1] avant de modifier tableau[1] en faisant free(tableau[1]); tableau[1]=tableau[2];, mais à la fin il faudra libérer ou bien tableau[1] ou bien tableau[2] mais pas les 2 car ils correspondent à la même région!
    2. ...
    J'avais rédigé ma réponse avec les 3 derniers cas.
    Puis j'ai ajouté la première possibilité, celle qui n'a aucun sens. Je viens de mettre en gras la partie de la phrase importante.

    Comme tu ne veux pas te soucier des désallocations, tu peux enlever le free() que tu as mis dans dans ton code.
    Toute donnée allouée DOIT être libérée.
    D'ailleurs finalement, il n'y a besoin de malloc()nulle part. Et même, pourquoi vouloir utiliser des tableaux?

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 814
    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 814
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par dalfab Voir le message
    D'ailleurs finalement, il n'y a besoin de malloc()nulle part.
    J'ai failli dire la même chose... mais j'ai vu que chaque pointeur allouait "i+1" * 1000 entiers (une espèce de tableau triangulaire). Or comme "i" est une variable...
    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]

Discussions similaires

  1. Calcul et Modification des valeurs dans un Tableau avec Java
    Par Khalfe dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 25/09/2015, 02h36
  2. Réponses: 1
    Dernier message: 28/08/2009, 02h45
  3. Modification des String dans un tableau par référence
    Par koukoula dans le forum Windows Forms
    Réponses: 13
    Dernier message: 06/06/2008, 15h29
  4. [C#] Affichage des lignes dans un tableau.
    Par maldufleur dans le forum ASP.NET
    Réponses: 4
    Dernier message: 21/04/2004, 11h28
  5. Décaler des valeurs dans un tableau
    Par sh2003 dans le forum Langage
    Réponses: 6
    Dernier message: 20/03/2004, 16h01

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