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 :

pb d'allocation de mémoire


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 17
    Par défaut pb d'allocation de mémoire
    bonjour tout le monde,

    j'ai un soucis d'allocation dynamique de mémoire. Ca se présente comme ça :

    j'ai un struct
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct element{
           float **tab;
           int taille;
           float distance;
     
           int choix[2];
     
           };
    tab représentera, une fois alloué, un tableau carré de taille "taille"

    j'ai aussi fait une fonction pour allouer de la mémoire à mon **tab
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void creation_tab(float **t, int n){
         t=(float**)malloc(n*sizeof(float*));
         if (!t) printf("oups");
         short i;
         for (i=0; i<n; i++)
             {t[i]=(float*)malloc(n*sizeof(float));     if (!t[i]) printf("oupss"); }
    }
    que j'appelle de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    struct element debut;
    creation_tab(debut.tab,5);
    jusque là, ça va, mais dès que je fais un accès à un élément de mon **tab en lecture ou en écriture j'ai une erreur d'exécution. J'ai beau retourner le problème dans tous les sens, je ne vois
    pas l'erreur.

  2. #2
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mai 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45

    Informations forums :
    Inscription : Mai 2004
    Messages : 102
    Par défaut
    Salut,

    Je comprends pas trop ce que tu veux faire.

    Un carré dynamique de quoi exactement ?

  3. #3
    Membre émérite
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Par défaut
    Il faut soit retourner le pointeur de pointeur pour pouvoir exploiter l'allocation dans le main, soit passer l'adresse de l'objet (ça sera donc un float *** !! )
    Solution simple :
    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
    float **creation_tab(float **t, int n)
    {
    int i ; // pas besoin de 'short' et 'faut' la declarer au debut de la fonction
     
    t=(float**)malloc(n*sizeof(float*));
      if (!t) printf("oups");     
         for (i=0; i<n; i++)
          {
             t[i]=(float*)malloc(n*sizeof(float));    
               if (!t[i]) printf("oupss"); 
          }
     
    return t ; // retourner 
    }
     
    // dans le main 
    debut.tab=creation_tab(debut.tab,n);
    Nas'

  4. #4
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Autant faire :
    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
    float **creation_tab(int n)
    {
    int i ; // pas besoin de 'short' et 'faut' la declarer au debut de la fonction
    float **t;   
    t=malloc(n*sizeof(float*)); // inutile de caster on est en C !!
      if (!t)
      {
        puts("oups");     
        return NULL;
       }
         for (i=0; i<n; i++)
          {
             t[i]=malloc(n*sizeof(float));   // idem que plus haut
               if (!t[i])
               {
                   puts("oupss");
                   // a toi de voir ce qu'il faut faire
                   // sans doute désallouer tout ce qui a été alloué
                   return NULL
                }
          }
     
    return t ; // retourner
    }
     
    // dans le main
    debut.tab=creation_tab(n);
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 17
    Par défaut
    merci nasky, c'est vrai que c'est tellement plus simple de faire une fonction qui renvoie le pointeur.

    pour ce qui est de la déclaration de la variable au début de la fonction, c'est dans la norme ??

    J'utilisais un short juste pour garantir 2 octets (ce programme pourra être amené à être compilé avec différents compilos et sur différents systèmes)

    Citation Envoyé par beloc
    Je comprends pas trop ce que tu veux faire.

    Un carré dynamique de quoi exactement ?
    c'est juste pour manipuler une matrice de réels. Et j'ai besoin d'autres variables annexes pour la gestion de mon problème, c'est pourquoi je prend un struct.

  6. #6
    Membre émérite
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Par défaut
    En C, on déclare les variables au début d'un bloc (encadré par { et } )
    Mais la variable n'est visible que dans le bloc. Donc déclarer les variables au début du main (et des fonctions) garantit qu'on puisse utiliser la variable partout dans le sous-programme.
    En C++ tu déclares où tu veux mais pas en C

    Nas'

  7. #7
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut Re: pb d'allocation de mémoire
    Citation Envoyé par shura
    j'ai un soucis d'allocation dynamique de mémoire. Ca se présente comme ça :
    C'est pas un problème d'allocation, mais un problème de paramètres.

    Rappel : les passage de paramètres se font uniquement par valeur en C.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void creation_tab(float **t, int n){
    <...>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    struct element debut;
    creation_tab(debut.tab,5);
    L'erreur est courante.

    Pour qu'une fonction modifie la valeur d'une variable, il faut passer l'adresse de cette variable

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    struct element debut;
    creation_tab(&debut.tab,5);
    pour ça, il faut un pointeur du bon type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void creation_tab(float ***t, int n){
    et modifier la fonction en conséquence. C'est horriblement lourd et une meilleure approche est d'utiliser une structure avec un constructeur (et un destructeur)
    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
     
    #include <stdio.h>
    #include <stdlib.h>
     
    #define DBG 0                   /* 0 1 2 3 */
     
    struct mat2
    {
       float **tab;
       size_t taille;
    };
     
    struct element
    {
       struct mat2 *mat;
       float distance;
     
       int choix[2];
    };
     
    void mat2_delete (struct mat2 *this)
    {
       if (this != NULL)
       {
          if (this->tab != NULL)
          {
             size_t i;
             for (i = 0; i < this->taille; i++)
             {
                free (this->tab[i]), this->tab[i] = NULL;
             }
     
             free (this->tab), this->tab = NULL;
          }
          free (this), this = NULL;
       }
    }
     
    struct mat2 *mat2_create (size_t n)
    {
       /* allocates the object */
       struct mat2 *this = malloc (sizeof *this);
     
    #if DBG==1
       free (this), this = NULL;
    #endif
       if (this != NULL)
       {
          this->taille = n;
          this->tab = NULL;
     
          {
             /* allocates the array of pointers */
             this->tab = malloc (sizeof *this->tab * n);
    #if DBG==2
             free (this->tab), this->tab = NULL;
    #endif
             if (this->tab != NULL)
             {
                size_t i;
     
                for (i = 0; i < n; i++)
                {
                   this->tab[i] = NULL;
                }
     
                /* allocates the array of data */
                for (i = 0; i < n; i++)
                {
                   this->tab[i] = malloc (n * sizeof *this->tab[i]);
    #if DBG==3
                   free (this->tab[i]), this->tab[i] = NULL;
    #endif
     
     
                   if (this->tab[i] == NULL)
                   {
                      mat2_delete (this), this = NULL;
                      break;
                   }
                }
             }
             else
             {
                mat2_delete (this), this = NULL;
             }
          }
       }
       return this;
    }
     
    int main (void)
    {
       struct element debut =
       {0};
     
       debut.mat = mat2_create (5);
       if (debut.mat != NULL)
       {
          debut.mat->tab[0][0] = 10;
     
          mat2_delete (debut.mat), debut.mat = NULL;
       }
       else
       {
          printf ("memory error (DBG=%d)\n", DBG);
       }
       return 0;
    }

  8. #8
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par shura
    pour ce qui est de la déclaration de la variable au début de la fonction, c'est dans la norme ??
    Ce que dit la norme C90, c'est qu'une définition de variable doit être faite en début de bloc. La norme C99 n'impose plus cette restriction.

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

Discussions similaires

  1. [Stratégie]Allocation/Desallocation mémoire
    Par lefait dans le forum Langage
    Réponses: 1
    Dernier message: 08/03/2006, 10h44
  2. [debutant] : Allocation de mémoire dynamique
    Par sam.fet dans le forum Langage
    Réponses: 5
    Dernier message: 15/02/2006, 14h58
  3. Problème d'allocation de mémoire dans la pile
    Par prophet666 dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 19/01/2006, 02h22
  4. [Debutant]Allocation de mémoire
    Par gwendal84 dans le forum C
    Réponses: 6
    Dernier message: 07/12/2005, 19h04
  5. Double allocation de mémoire
    Par hunter001 dans le forum C++
    Réponses: 16
    Dernier message: 25/08/2005, 13h53

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