allocation en C - C - Programmation
Marsh Posté le 15-02-2006 à 16:22:00
oui mais ça quelle effet sur la mémoire? c'est lequel qui est le plus interessant à faire?
Marsh Posté le 15-02-2006 à 16:23:47
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
Marsh Posté le 15-02-2006 à 16:31:21
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.
Marsh Posté le 15-02-2006 à 16:32:48
ouais, mais tu pourrais ecrire
malloc( roger * sizeof(int))
alors que tu ne peux pas ecrire
int toto[roger];
Marsh Posté le 15-02-2006 à 16:34:25
ReplyMarsh Posté le 15-02-2006 à 16:35:32
ReplyMarsh Posté le 15-02-2006 à 16:38:36
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
Marsh Posté le 15-02-2006 à 16:45:19
chrisbk a écrit : vala, forcement y'en a un qui allait venir faire son expert et foutre la merde |
(ouais je sais, c'est nase auprès d'un débutant de sortir ce sort de chose )
mbarekh a écrit : et ca voudrait dire quoi malloc( roger * sizeof(int)) ? |
"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.
Marsh Posté le 15-02-2006 à 16:50:44
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?
Marsh Posté le 15-02-2006 à 17:09:28
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..
Marsh Posté le 15-02-2006 à 17:12:28
mbarekh a écrit : si j'ai bien compris je peux faire cela: |
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 :
|
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.
Marsh Posté le 15-02-2006 à 19:48:19
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 :
|
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 :
|
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)
Marsh Posté le 15-02-2006 à 19:59:26
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
Marsh Posté le 15-02-2006 à 20:55:46
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.
Merci pour vos remarques par rapport à mes erreurs dans mon précédent post, je l'ai modifié.
Marsh Posté le 15-02-2006 à 21:43:18
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 :
|
Marsh Posté le 15-02-2006 à 16:13:09
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