Allocation dynamique d'un tableau

Allocation dynamique d'un tableau - C - Programmation

Marsh Posté le 17-05-2006 à 19:10:41    

Bonjour,
 
je voudrais savoir comment faire pour allouer un tableau dynamiquement lorsque l'on doit augmenter la taille d'un tableau au fur et à mesure des besoins.
 
Merci

Reply

Marsh Posté le 17-05-2006 à 19:10:41   

Reply

Marsh Posté le 17-05-2006 à 19:11:38    

malloc et realloc

Reply

Marsh Posté le 17-05-2006 à 19:23:21    

mais bon un tableau c'est pas dynamique par définition :D

Reply

Marsh Posté le 17-05-2006 à 19:55:55    

Bonjour,
 
Est-ce que quelqu'un pourrait m'écrire un exemple pour que ça me serve de model ?
 
Merci

Reply

Marsh Posté le 17-05-2006 à 20:28:51    

int * tab;
tab = (int*) calloc (10,sizeof(int));
 
alloue un tableau de 10 cases de la taille d'un entier

Reply

Marsh Posté le 17-05-2006 à 20:34:54    

+ realloc pour changer sa taille

Reply

Marsh Posté le 17-05-2006 à 20:35:43    

pour répondre très précisément au titre :
 

Code :
  1. #include <stdlib.h>
  2. int main()
  3. {
  4.         int (*p)[10];
  5.         p = malloc(sizeof *p);
  6.         free(p);
  7.         return 0;
  8. }

Reply

Marsh Posté le 17-05-2006 à 20:41:08    

ouai, voila une allocation dynamique d'un tableau
 
a mon avis Gattuso voulais plutot savoir comment on peut faire si la taille du tableau est inconnue à la compilation et qui peut en plus changer au cours de l'execution

Reply

Marsh Posté le 17-05-2006 à 21:55:50    

Pour compléter la réponse de Taz, un type d'utilisation pourrait-être :
Lecture de ligne dans un fichier(ce n'est pas la taille du buffer de lecture qui est l'intérêt ici, ni non plus,  
le fait de virer le '\n' à la fin de la ligne)
 

Code :
  1. char **lecture(FILE *f)
  2. {
  3.    char **p ;
  4.    char *ptr;
  5.    int maxlines = MAXLINES;
  6.    int nbcur;
  7.    char Buf[128];
  8.    p = malloc(maxlines * sizeof(*p));
  9.    if (p == NULL)
  10.    {
  11.       fprintf(stderr, "Pb allocation mémoire\n" );
  12.       return p;
  13.    }
  14.    nbcur = 0;
  15.    while(fgets(Buf, sizeof(Buf), stdin)) != NULL)
  16.    {
  17.        nbcur++;
  18.        // ici on a atteint le maximum de pointeur de lignes allouées
  19.        if (nbcur == maxlines)
  20.        {
  21.            char **tmp;
  22.            maxlines *= 2;
  23.            // il faut tester le retour de realloc, s'il est NULL? p reste valide
  24.            tmp = realloc(p, maxlines);
  25.            if (tmp == NULL)
  26.            {
  27.               fprintf(stderr, "Pb allocation mémoire\n" );
  28.               return p;
  29.            }
  30.            p = tmp;
  31.        }
  32.        // on vire la fin de ligne
  33.        ptr = strchr(Buf, '\n');
  34.        if (ptr != NULL)
  35.           *ptr = 0;
  36.        p[nbcur] = strdup(Buf);
  37.    }
  38.     return p;
  39. }


Message édité par Trap D le 17-05-2006 à 21:56:41
Reply

Marsh Posté le 18-05-2006 à 00:46:54    

bjone a écrit :

mais bon un tableau c'est pas dynamique par définition :D


Ah ? Il n'existe pas de tableaux dynamiques, selon toi ?
 
Intéressant. Tu peux développer ?

Message cité 1 fois
Message édité par Emmanuel Delahaye le 18-05-2006 à 00:49:41

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-05-2006 à 00:46:54   

Reply

Marsh Posté le 18-05-2006 à 00:48:33    

eljoundi a écrit :

int * tab;
tab = (int*) calloc (10,sizeof(int));
 
alloue un tableau de 10 cases de la taille d'un entier


Pourquoi le cast ? Assure toi plutôt que <stdlib.h> est bien inclus.
 
http://mapage.noos.fr/emdel/notes.htm#malloc
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-05-2006 à 10:32:54    

Emmanuel Delahaye a écrit :

Ah ? Il n'existe pas de tableaux dynamiques, selon toi ?
 
Intéressant. Tu peux développer ?


 
c'est un bloc mémoire que tu alloues :D enfin bin c'était histoire de faire le lourd  :cry:

Reply

Marsh Posté le 18-05-2006 à 11:19:10    

bjone a écrit :

c'est un bloc mémoire que tu alloues :D enfin bin c'était histoire de faire le lourd  :cry:


Et un tableau, c'est pas un bloc mémoire ? C'est quoi alors ? Un bloc de glace ?
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-05-2006 à 11:46:03    

bon allez spa grave ;)
(dla glace à la poire avec de la bannane flambée)


Message édité par bjone le 18-05-2006 à 11:46:41
Reply

Marsh Posté le 18-05-2006 à 20:19:23    

question stupide (j'ai la flemme de tester aussi!)

Code :
  1. tmp = realloc(p, maxlines);
  2. ...
  3. p = tmp;


Si 'p' pointe vers une zone memoire contenant deja des données, ces données sont elle recopiées automatiquement dans tmp lors de la reallocation ou c'est a nous de reremplir?
 
Si elle ne sont pas recopiés, quel est l'interet du realloc par rapport a un second appel a malloc/calloc?

Message cité 2 fois
Message édité par breizhbugs le 18-05-2006 à 20:19:53
Reply

Marsh Posté le 18-05-2006 à 20:39:59    

tout ca est dit dans la doc  :)  
 

Citation :

(j'ai la flemme de tester aussi!)


 
tu veux faire de la retro ingenierie sur une fonction documentée ?
 

Citation :

Si 'p' pointe vers une zone memoire contenant deja des données


 
ca veut dire quoi ?

Reply

Marsh Posté le 18-05-2006 à 21:37:59    

Ah oui effectivement c'est dans la doc, j'avais mal lu desolé.
il y a conservation des données si taille realloc superieure et tronquation des données sinon.

Reply

Marsh Posté le 18-05-2006 à 23:11:12    

breizhbugs a écrit :


Code :
  1. tmp = realloc(p, maxlines);
  2. ...
  3. p = tmp;


Si 'p' pointe vers une zone memoire contenant deja des données, ces données sont elle recopiées automatiquement dans tmp lors de la reallocation<...>


Aucune donnée n'est copiée dans tmp. Uniquement l'adresse du nouveau bloc alloué.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 19-05-2006 à 11:35:35    

0x90 a écrit :

malloc et realloc


En fait, on peut n'utiliser que realloc. Si le pt passé à realloc est NULL, le realloc fait lui-même le malloc initial...
 

breizhbugs a écrit :

Si elle ne sont pas recopiés, quel est l'interet du realloc par rapport a un second appel a malloc/calloc?


Ben aucun donc forcément elles sont recopiées. Mais si elles n'étaient pas recopiées (ou si realloc n'existait pas), on pourrait quand-même faire du stockage dynamique d'éléments en utilisant une liste chaînée évidemment plus lourd (j'en connais qui font ça :sol:)
 

breizhbugs a écrit :

...et tronquation des données sinon.


Tiens ? Je croyais que realloc ne faisais rien si la nouvelle taille était inférieure à l'ancienne pour optimiser ?

Message cité 2 fois
Message édité par Sve@r le 19-05-2006 à 11:48:40

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 19-05-2006 à 11:51:16    

Sve@r a écrit :


Tiens ? Je croyais que realloc ne faisais rien si la nouvelle taille était inférieure à l'ancienne pour optimiser ?


 
Totalement dépendant de l'implé [:spamafote]

Reply

Marsh Posté le 19-05-2006 à 11:58:20    

0x90 a écrit :

Totalement dépendant de l'implé [:spamafote]


Merci  :jap:  


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 19-05-2006 à 13:32:38    

Sve@r a écrit :

Mais si elles n'étaient pas recopiées (ou si realloc n'existait pas), on pourrait quand-même faire du stockage dynamique d'éléments en utilisant une liste chaînée évidemment plus lourd (j'en connais qui font ça :sol:)


C'est malheureusement le cas dans des langages comme Fortran90  :'(

Message cité 2 fois
Message édité par franceso le 19-05-2006 à 13:33:00

---------------
TriScale innov
Reply

Marsh Posté le 19-05-2006 à 13:37:02    

franceso a écrit :

C'est malheureusement le cas dans des langages comme Fortran90  :'(


 
Fortran90, langage ?  [:0x90]

Reply

Marsh Posté le 19-05-2006 à 14:03:16    

franceso a écrit :

C'est malheureusement le cas dans des langages comme Fortran90  :'(


 
le cas de quoi ? tu peux etre plus precis ?

Reply

Marsh Posté le 19-05-2006 à 14:19:19    

skelter a écrit :

le cas de quoi ? tu peux etre plus precis ?


En fortran90, il y a des fonctionalités d'allocation dynamique (en gros un équivalent de calloc), mais on ne dispose malheureusement pas d'un équivalent de realloc. Donc si tu veux faire du stockage dynamique les deux possibilités sont :
1- quand tu débordes, tu alloues un nouveau tableau plus grand, tu copies les valeurs et tu désalloue le premier tableau
2- tu implémentes une liste chainée ou une variante du même genre (par exemple j'utilise des liste chainées de tableaux de 1000 éléments pour éviter d'avoir trop d'allocations dynamiques tout en ne surdimensionnant pas trop la place utilisée)
 
inutile de préciser que la première méthode est plus facile à implémenter mais pas terrible niveau performances.


---------------
TriScale innov
Reply

Marsh Posté le 19-05-2006 à 15:14:05    

franceso a écrit :

En fortran90, il y a des fonctionalités d'allocation dynamique (en gros un équivalent de calloc), mais on ne dispose malheureusement pas d'un équivalent de realloc. Donc si tu veux faire du stockage dynamique les deux possibilités sont :
1- quand tu débordes, tu alloues un nouveau tableau plus grand, tu copies les valeurs et tu désalloue le premier tableau
2- tu implémentes une liste chainée ou une variante du même genre (par exemple j'utilise des liste chainées de tableaux de 1000 éléments pour éviter d'avoir trop d'allocations dynamiques tout en ne surdimensionnant pas trop la place utilisée)
 
inutile de préciser que la première méthode est plus facile à implémenter mais pas terrible niveau performances.


 
oui, ok, mais c'est loin d'etre specifique à fortran 90, c'est le cas dans tout les langages.
 
En générale on choisie la premiere solution avec une strategie de reallocation pour eviter de reallouer à chaque demande d'agrandissement de la zone memoire, c'est ce que fait realloc en C dans ton dos (mais les details dependent de l'implementation, on sait juste que realloc n'implique pas un deplacement de la zone memoire) et std::vector en C++. Fortran 90 n'offre pas ce support intrinsequement mais tu peux toujours le developper toi meme (a moins qu'il existe une bibliotheque qui le gere).
 
En ce qui concerne le choix d'une liste chainée, il y a beaucoup d'autre facteur à considérés, autres que la vitesse d'ajoue d'element en fin de sequence (le choix d'un type de conteneur c'est un autre probleme).

Reply

Marsh Posté le 19-05-2006 à 15:21:47    

Citation :


mais les details dependent de l'implementation, on sait juste que realloc n'implique pas un deplacement de la zone memoire


 
??


Message édité par 0x90 le 19-05-2006 à 15:42:03
Reply

Marsh Posté le 19-05-2006 à 15:26:17    

skelter a écrit :

oui, ok, mais c'est loin d'etre specifique à fortran 90, c'est le cas dans tout les langages.

Je sais bien. Je  ne dis pas que c'est spécifique à F90, c'était juste pour donner un exemple de langage qui ne fournit pas de realloc.
 

skelter a écrit :

En générale on choisie la premiere solution avec une strategie de reallocation pour eviter de reallouer à chaque demande d'agrandissement de la zone memoire, c'est ce que fait realloc en C dans ton dos (mais les details dependent de l'implementation, on sait juste que realloc n'implique pas un deplacement de la zone memoire) et std::vector en C++. Fortran 90 n'offre pas ce support intrinsequement mais tu peux toujours le developper toi meme (a moins qu'il existe une bibliotheque qui le gere).

Effectivement on peut toujours réimplémenter des fonctionnalités semblables à realloc (comme dans la solution 1). La différence avec le C c'est qu'en fortran tu es *toujours* obligé de recopier tes données. Il n'y a pas à ma connaissance de bibliothèque qui gère ce genre de chose mais c'est de toutes façons assez simple pour pouvoir être réimplémenté à la main au cas par cas.
 

skelter a écrit :

En ce qui concerne le choix d'une liste chainée, il y a beaucoup d'autre facteur à considérés, autres que la vitesse d'ajoue d'element en fin de sequence (le choix d'un type de conteneur c'est un autre probleme).

Dans le cas qui me concerne, je n'utilise une liste chainée que temporairement. Lorsque j'ai fini de remplir toutes les valeurs, je recopie la liste dans un tableau. Ceci me permet de disposer ensuite d'un espace mémoire contigu pour faire des calculs efficaces.


---------------
TriScale innov
Reply

Marsh Posté le 19-05-2006 à 16:04:33    

skelter a écrit :

(mais les details dependent de l'implementation, on sait juste que realloc n'implique pas un deplacement de la zone memoire)


Ben non. Pourquoi realloc() retournerait-il une adresse si c'était vrai ?
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 19-05-2006 à 16:14:20    

Emmanuel Delahaye a écrit :

skelter a écrit :

on sait juste que realloc n'implique pas un deplacement de la zone memoire

Ben non. Pourquoi realloc() retournerait-il une adresse si c'était vrai ?


Il me semble bien (comme skelter, si j'ai bien compris) que realloc ne déplace pas toujours la mémoire. S'il est possible d'allouer l'espace supplémentaire juste derrière le tableau déjà alloué, il me semblait que realloc se contentait juste d'allouer cet espace et de laisser la première partie du tableau en place (en renvoyant l'adresse inchangée). Il est quand même nécessaire que realloc() renvoie un pointeur pour le cas où il y a quand même eu un déplacement.


Message édité par franceso le 19-05-2006 à 16:15:24

---------------
TriScale innov
Reply

Marsh Posté le 19-05-2006 à 16:34:42    

oui,
 

Emmanuel Delahaye a écrit :

Ben non. Pourquoi realloc() retournerait-il une adresse si c'était vrai ?


 
je faisais la négation de "implique un deplacement" qui est fausse, enfin peut etre que c'est mal dit  :ange:

Reply

Marsh Posté le 26-05-2006 à 19:33:44    

Citation :

Ben non. Pourquoi realloc() retournerait-il une adresse si c'était vrai ?
Il me semble bien (comme skelter, si j'ai bien compris) que realloc ne déplace pas toujours la mémoire.


Non.
Il ne le fait que s'il a à le faire.
D'ailleurs, il est amusant de noter qu'il peut déplacer les données même lorsqu'on réduit la taille.
 

Citation :


S'il est possible d'allouer l'espace supplémentaire juste derrière le tableau déjà alloué, il me semblait que realloc se contentait juste d'allouer cet espace et de laisser la première partie du tableau en place (en renvoyant l'adresse inchangée). Il est quand même nécessaire que realloc() renvoie un pointeur pour le cas où il y a quand même eu un déplacement.


Aïe.
Ce n'est pas un tableau qui est alloué, c'est une zone de mémoire.
 
Un tableau n'a rien à voir avec un pointeur sur une zone allouée par malloc, si c'est ce que tu sous-entends.
 
Par exemple, tu obtient la taille dun tableau par sizeof(tab)
Si tu fais ça sur un pointeur, il va te renvoyer la taille du pointeur, soit généralement 4 byte.
Y'a pas de façon portable de récupérer la taille du bloc alloué.

Reply

Marsh Posté le 26-05-2006 à 20:42:38    

simple_stupid a écrit :


Non.
Il ne le fait que s'il a à le faire.


 
c'est bien ce que franceso dit  :??:  
 

simple_stupid a écrit :


D'ailleurs, il est amusant de noter qu'il peut déplacer les données même lorsqu'on réduit la taille.


 
detail d'implementation, par exemple si malloc gere de facon differente les petites allocations et les grandes allocations le passage d'une tranche à l'autre peut entrainer un deplacement meme si ce n'est pas necessaire. (pas sur)

Reply

Marsh Posté le 27-05-2006 à 12:42:27    

Emmanuel Delahaye a écrit :

Ben non. Pourquoi realloc() retournerait-il une adresse si c'était vrai ?


Je pense qu'il voulait signifier "n'implique pas forcément...".
De toute façon, malloc dépend de la stratégie de gestion mémoire par l'OS, donc c'est forcément dépendant de l'implémentation.


Message édité par el muchacho le 27-05-2006 à 12:43:31

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed