Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3418 connectés 

  FORUM HardWare.fr
  Programmation
  C

  allocation en C

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

allocation en C

n°1306448
mbarekh
Posté le 15-02-2006 à 16:13:09  profilanswer
 

Bonjour,
Je suis un débutant en C et je voudrais poser une question à propos de l'allocation en C.
En fait, je voudrias avoir la différence entre:
 
int tab[100];
 
et  
 
tab = malloc(sizeof(int) * 10);
 
merci d'avance :)

mood
Publicité
Posté le 15-02-2006 à 16:13:09  profilanswer
 

n°1306460
chrisbk
-
Posté le 15-02-2006 à 16:17:45  profilanswer
 

allocation statique
 
allocation dynamique

n°1306472
mbarekh
Posté le 15-02-2006 à 16:22:00  profilanswer
 

oui  mais ça quelle effet sur la mémoire? c'est lequel qui est le  plus interessant à faire?

n°1306477
chrisbk
-
Posté le 15-02-2006 à 16:23:47  profilanswer
 

si tu connais a l'avance la taille de ton tableau et que cest pas un truc enorme, static est bien
Si tu ne connais pas a l'avance la taille, ou si tu sais que tu veux un machin bien lourd (plus de 5ko je dirais), vise dynamique
 
Si tu veux que ton tableau survive a la fonction dans laquelle il est crée : dynamique
 

n°1306493
mbarekh
Posté le 15-02-2006 à 16:31:21  profilanswer
 

mais lorsque je fais malloc(100*sizeof(int)) , cela suppose que je fixe la taille de mon tableau. par exemple ici la taille de mon tableau(d'entiers) est 100.
 

n°1306497
chrisbk
-
Posté le 15-02-2006 à 16:32:48  profilanswer
 

ouais, mais tu pourrais ecrire
 
malloc( roger * sizeof(int))
 
alors que tu ne peux pas ecrire
 
int toto[roger];

n°1306501
Elmoricq
Modérateur
Posté le 15-02-2006 à 16:34:25  profilanswer
 

chrisbk a écrit :

alors que tu ne peux pas ecrire
 
int toto[roger];


 
En C99, si.  [:dawa]

n°1306504
chrisbk
-
Posté le 15-02-2006 à 16:35:32  profilanswer
 

vala, forcement y'en a un qui allait venir faire son expert et foutre la merde [:pingouino]

n°1306508
mbarekh
Posté le 15-02-2006 à 16:38:36  profilanswer
 

et ca voudrait dire quoi malloc( roger * sizeof(int)) ?
le problème est que je ne comprends pas pourquoi  tu dis que avec malloc, on peut ne peux pas connaitre la taille en avance?
désolé si j'insiste

n°1306517
Elmoricq
Modérateur
Posté le 15-02-2006 à 16:45:19  profilanswer
 

chrisbk a écrit :

vala, forcement y'en a un qui allait venir faire son expert et foutre la merde [:pingouino]


 
[:klem3i1]
(ouais je sais, c'est nase auprès d'un débutant de sortir ce sort de chose  [:petrus75] )
 

mbarekh a écrit :

et ca voudrait dire quoi malloc( roger * sizeof(int)) ?
le problème est que je ne comprends pas pourquoi  tu dis que avec malloc, on peut ne peux pas connaitre la taille en avance?
désolé si j'insiste


 
"roger" est une variable quelconque qui peut être calculée juste avant le malloc(). Tu ne connais pas sa valeur à la compilation, elle ne sera disponible qu'au tout dernier moment de l'exécution.
 
Comme l'a dit chrisbk, l'allocation dynamique sert essentiellement soit dans ce cas-là, soit pour qu'une allocation soit "persistante", c'est-à-dire que la mémoire utilisée à cet effet restera réservée, jusqu'à ce que tu la libères explicitement (avec free() ). Dans le cas d'un tableau statique, dès que tu sors de la fonction, le tableau n'existe plus.

mood
Publicité
Posté le 15-02-2006 à 16:45:19  profilanswer
 

n°1306519
mbarekh
Posté le 15-02-2006 à 16:50:44  profilanswer
 

si j'ai bien compris je peux faire cela:
int roger ;
int tab[];
tab = malloc( roger * sizeof(int));
roger = 10; // la taille du tableau est 10
roger = 50;// la taille devient 50?

n°1306542
francky06l
Posté le 15-02-2006 à 17:09:28  profilanswer
 

Euh non, plutot :
 
roger = 10;
int *tab = malloc(roger *sizeof(int));
 
// changement de size
 
free(tab);
roger = 50;
tab = malloc(roger * sizeof(int));
 
l'allocation est dynamique mais la taille allouee de bouge pas seule, il faut explicitement le liberer et reallouer..
Bon y a aussi realloc(), mais on va y a aller doucement..

n°1306545
mbarekh
Posté le 15-02-2006 à 17:11:00  profilanswer
 

il fait quoi le realloc?

n°1306547
Elmoricq
Modérateur
Posté le 15-02-2006 à 17:12:28  profilanswer
 

mbarekh a écrit :

si j'ai bien compris je peux faire cela:
int roger ;
int tab[];
tab = malloc( roger * sizeof(int));
roger = 10; // la taille du tableau est 10
roger = 50;// la taille devient 50?


 
Non.
A ce stade, je ne saurais trop te conseiller un livre de C, tu te lances trop tôt dans le code sans connaître les principes de base.
 
Mais si tu tiens à un exemple, tu peux utiliser ceci :

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. /* Tire un nombre aleatoire, entre 1 et max */
  5. unsigned tirage(unsigned max)
  6. {
  7.     if ( max == 0 )
  8.         max = RAND_MAX;
  9.    
  10.     return 1+(unsigned)((double)rand()/((double)RAND_MAX+1)*max);
  11. }
  12. int main(void)
  13. {
  14.    unsigned cases;
  15.    int *tableau = NULL;
  16.    /* Initialisation des nombres aléatoires */
  17.    srand(time(NULL));
  18.  
  19.    /* Tirage aléatoire d'un nombre de cases, entre 1 et 20 */
  20.    cases = tirage(20);
  21.    printf("Nombre de cases : %u\n", cases);
  22.    /* Allocation dynamique et remplissage si l'allocation a reussi */
  23.    tableau = malloc( cases * sizeof *tableau );
  24.    if ( tableau != NULL )
  25.    {
  26.        unsigned i;
  27.      
  28.        for( i = 0; i < cases; i++ )
  29.        {
  30.            tableau[i] = tirage(100);
  31.        }
  32.      
  33.        /* Affichage du contenu du tableau a l'ecran */
  34.        for( i = 0; i < cases; i++ )
  35.        {
  36.            printf("Case n°%u = %u\n", i + 1, tableau[i]);
  37.        }
  38.      
  39.        /* Liberation de la memoire occupee */
  40.        free(tableau);
  41.    }
  42.  
  43.    return EXIT_SUCCESS;
  44. }


 
Ce petit programme alloue un tableau dynamique dont le nombre de case est aléatoire.
Il remplit ces cases, puis les lit et les affiche à l'écran. J'espère que ça t'aidera à comprendre le principe de l'allocation dynamique.
Les commentaires devraient t'aider à comprendre ce que fait ce programme.


Message édité par Elmoricq le 15-02-2006 à 17:13:58
n°1306553
mbarekh
Posté le 15-02-2006 à 17:16:28  profilanswer
 

merci bcp c'est très gentil :)

n°1306654
pj_crepes
Posté le 15-02-2006 à 19:48:19  profilanswer
 

En fait pour essayer de t'éclairer mbarekh, en c on peut arriver au même résultat avec un tableau et avec une allocation dynamique.
 
En fait déjà pour commencer faut pas perdre de l'esprit que le C est un langage compilé, donc que tout ce que tu fais va être transformé en langage machine (c'est ce que l'on appelle la compilation).
 
Et il se trouve que si tu utilises un tableau le code assembleur généré ne sera pas le même que si tu utilises une allocation dynamique avec malloc() ou calloc().
Le code sera différent car le compilateur ne va gérer la mémoire de la même façon dans les deux cas.
 
 
TABLEAU :
 
il s'utilise de la façon suivante :

Code :
  1. #include <stdio.h>
  2. #define NB 20
  3. ...
  4. int tab[NB];
  5. int k;
  6. for(k=0; k<NB; ++k)
  7.    tab[k] = k;
  8. printf("tab[k] = %d", k, tab[k]);


 
Dans ce cas le compilateur réserve un espace en mémoire de NB*sizeof(int), cette taille n'est pas modifiable (cette taille restera la même jusqu'à la fin de la vie du tableau).
Cet espace mémoire sera géré par le compilateur comme un tableau d'où le nom :) :
- un tableau de NB cases pourra être parcouru par un index allant de 0 à NB-1
- chaque case un tableau sera considéré comme une varaible de type int (dans notre exemple).
- sizeof(tab) donnera la taille du tableau en octets (NB*sizeof(int) ici)
 
ALLOCATION DYNAMIQUE :
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define NB 20
  4. ...
  5. int *tab;
  6. int k;
  7. if( (tab = malloc(NB*sizeof(int)) == NULL )
  8. {
  9.    fprintf(stderr, "Erreur d'allocation memoire !\n" );
  10.    exit(EXIT_FAILURE);
  11. }
  12. for(k=0; k<NB; ++k)
  13.    tab[k] = k;            // ou *(tab+k) = k;
  14. printf("tab[k] = %d", k, tab[k]);     // ou printf("tab[k] = %d", k, *(tab+k));  
  15. free(tab);


 
Dans ce cas malloc() alloue une place en mémoire d'une taille de NB*sizeof(int).
Cette fois ci le compilateur ne considère pas cet espace comme un tableau, donc le comportement va changer.
Il est possible de changer la taille de cet espace mémoire à l'aide de la fonction realloc(), cette fonction renvoyant un pointeur vers le nouvel espace mémoire alloué.
 
- on peut parcourir cet espace mémoire comme un tableau
- sizeof(tab) donnera la taille d'une adresse en mémoire (soit 4 octets sur un PC en général)


Message édité par pj_crepes le 15-02-2006 à 21:01:13
n°1306657
skelter
Posté le 15-02-2006 à 19:59:26  profilanswer
 

Citation :

sizeof(tab) donnera la taille du tableau (NB ici)


 
attention, la taille et non le nombre d'éléments  (pas NB)  
T tab[N] -> sizeof tab == N * sizeof(T)
 

Citation :

Dans ce cas le compilateur alloue une place en mémoire d'une taille de NB*sizeof(int).


c'est malloc qui alloue, le compilateur génère juste le code d'appel de malloc et le reste il s'en fout et c'est important car ca montre bien tout ce qu'il ne peut pas controler
 

Citation :

Cette fois ci le compilateur ne considère pas cet espace comme un tableau, donc le comportement va changer.


oui, tab est un pointeur, ce n'est pas un tableau
 

Citation :

sizeof(tab) donnera la taille d'une adresse en mémoire (soit 4 octets sur un PC en général)


sizeof tab == sizeof(void *) tout simplement puisqu'on lui passe un objet de type pointeur, et si on lui passe un tableau il renvoi bien la taille du tableau, c'est ce qu'on attend de sizeof. le tout c'est d'avoir compris que tableau != pointeur


Message édité par skelter le 15-02-2006 à 19:59:59
n°1306683
pj_crepes
Posté le 15-02-2006 à 20:55:46  profilanswer
 

Désolé pour l'erreur que j'ai faite en effet dans le cas d'un tableau sizeof(tab) donne la taille en octets et non et non NB.
 
Pour ce qui est de la gestion de la mémoire, je suis d'accord avec toi skelter sur le faite que c'est malloc qui alloue.
C'est parce que je me suis mal exprimé.
En fait il est vrai que c'est un point important (le fait que se soit malloc() qui alloue la mémoire) en revanche y a un deuxièdme point important, c'est que le compilateur gère la mémoire.
 
Par exemple dans le cas d'un tableau c'est lui qui fixe l'endroit en mémoire où il va se trouver.
Si l'on déclare une variable "static" elle ne sera pas rangé au même endroit qu'un variable déclérée "auto"; bon après évidemment y a des histoires de visibilitées mais bref passons.
 
Enfin il faut quand même avoir l'espris que la gestion de mémoire (hors allocation dynamique) est une grosse partie du travail d'un compilateur.
 
 
Pour ce qui est du test sur le malloc() Emmanuel D elahaye, c'est vrai que c'est mieux.
Je l'ai pas mis parce que je n'y ait pas pensé en faisant l'exemple.
Mais étant donné qu'on a aucun système de gestion des exceptions en C il est vrai que sa serait dommage de se priver des remontés d'erreur. :)
 
 
:edit:
 
Merci pour vos remarques par rapport à mes erreurs dans mon précédent post, je l'ai modifié.


Message édité par pj_crepes le 15-02-2006 à 21:00:10
n°1306711
Sve@r
Posté le 15-02-2006 à 21:43:18  profilanswer
 

mbarekh a écrit :

il fait quoi le realloc?


Il te permet d'agrandir un tableau alloué avec "malloc()" tout en conservant les éléments du tableau déjà présents.
 
La syntaxe générale d'allocation/réallocation (on va dire pour un tableau de type "int" ) c'est :


int *tab;
int *tmp;
...
tab=malloc (n * sizeof(int));
if (tab == NULL)
{
      // Gestion du cas où on n'a pas pu allouer
      // En général, on arrête ici la fonction car le reste ne sert plus à rien
}
 
// Donc ici, "tab" a été alloué puisque sinon, on aurait quitté la fonction
...
...
traitement de "tab"
...
...
 
// Ici, on arrive sur un cas où il faut agrandir "tab" (parce que ça sert à rien de le diminuer)
n=f(n);    // f() strictement croissante donc "n" a augmenté de valeur
 
// Réallocation
tmp=realloc(tab, n * sizeof(int));
if (tmp == NULL)
{
      // Gestion du cas où on n'a pas pu réallouer
      // Comme on n'a pas perdu "tab", la gestion peut être assez fine...
}
else
{
     // Puisque "tmp" contient le nouveau "tab" tout en ayant conservé ses valeurs
     // Ne reste plus qu'à remplacer l'ancien par le nouveau
     tab=tmp;
}
...
...
on continue à utiliser "tab" qui a grandi en taille
...
...
 
// Ici on a fini avec "tab"
free(tab),


 
 


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

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  allocation en C

 

Sujets relatifs
Allocation en deux temps d'un vector<vector<float>>(Debutant!) probleme d'allocation c99
structures et allocationAllocation correcte en C
[C][linux] msgget : problème d'allocationallocation dynamique
probleme allocation memoireProhiber l'allocation/destruction d'objet
[Class] Constructeur et allocation de mémoire.Allocation pour FPU
Plus de sujets relatifs à : allocation en C


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)