salut :) ,
j'ai un petit problème lors de la déclaration d'un tableau dynamique à l'aide des intructions suivantes :
etCode:int t[];
car dans le cours j'ai vue que ce sont des déclarations dynamique mais ça ne marhe pasCode:char s[];
et merci
Version imprimable
salut :) ,
j'ai un petit problème lors de la déclaration d'un tableau dynamique à l'aide des intructions suivantes :
etCode:int t[];
car dans le cours j'ai vue que ce sont des déclarations dynamique mais ça ne marhe pasCode:char s[];
et merci
Bonjour,
Dans quel cours ? :koi:
Le nombre d'élément est normalement fixé à la compilation soit par le nombre indiqué entre les crochet Type tab[4] soit par le nombre d'élément qu'on lui donne lors de l'initialisation s'il n'y a rien entre crochet Type tab[] = {4,5,5}.
A noter que char toto[] = "ee" est équivalant à char toto[] = {'e', 'e', '\0'}.
Mais depuis le C99 on peut "tricher" en ayant des tableaux dont la taille est défini à l'initialisation (utilise l'allocation dynamique me semble) :
C'est une "Variable-length array".Code:
1
2
3
4 void foo(int nbElement) { Type tab[nbElement]; }
Sinon, tu peux utiliser l'allocation dynamique avec free, malloc et realloc.
C'est en général "stack-allocated" (je ne suis pas sûr de ce que tu entends par "allocation dynamique").
La notation "tab[]" peut se rencontrer dans les paramètres d'une fonction:
Il y a peut-être une subtilité avec "int *tab" mais elle m'échappe là :)Code:
1
2
3
4 int foo(int tab[]) { return tab[2]; }
Par "allocation dynamique" j'entends allocation dynamique ;)
Il n'y a aucune différence entre int * tab et int tab[] (et même avec int tab[X]) dans le prototype d'une fonction, ce sont tous 3 des pointeurs et non des tableaux.
Les VLA sont toujours en allocation automatique (ne peuvent être créés que comme variables locales)Citation:
Mais depuis le C99 on peut "tricher" en ayant des tableaux dont la taille est défini à l'initialisation (utilise l'allocation dynamique me semble) :
C'est une "Variable-length array".Code:
1
2
3
4 void foo(int nbElement) { Type tab[nbElement]; }
Pour moi "dynamique" est en opposition à statique : c'est la différence entre "connu à la compilation" et "connu à l'exécution". Je range les VLA dans de l'allocation dynamique, tout comme l'utilisation d'alloca().
Vu que c'est du C99, ça peut expliquer que ce n'est pas inclus dans le cours, mais le terme "allocation dynamique" reste du coup ambiguë. :aie:
Ce n'est pas ambigu : il y a trois (et non deux) méthodes de créations d'objets (reconnues par la norme) : allocation statique, allocation automatique et allocation dynamique. Elles se différencient par la méthode de création de l'objet et sa durée de vie.
Je n'ai pas trouvé de référence à "allocation dynamique" dans la norme justement:
D'où le fait que "dynamic" peut recouvrir "allocated" ET "automatic". Mais je suis preneur d'un pointeur sur le standard qui répondrait à ça :zoubi:Citation:
An object has a storage duration that determines its lifetime. There are three storage durations: static, automatic, and allocated. Allocated storage is described in 7.20.3.
Sauf que si la norme ne parle pas de "dynamic allocation", alors rien ne te permet de dire que "dynamic" regroupe "allocated" et "automatic", en toute logique :P
La partie que tu cites est le point 6.2.4 Storage durations of objects. Es-tu allé voir le point cité, 7.20.3 Memory management functions? On y retrouve tous les fonctions de ce qu'on appelle couramment "allocation dynamique".
Pour rester dans une nomenclature plus proche de l'universalité, on devrait dire "allocation statique", "allocation sur la pile", "allocation sur le tas". Wikipedia parle de "dynamic memory allocation" pour ce qui est sur le tas, mais l'article n'est pas exceptionnel non plus.
EDIT : dans un autre article, on trouve encore une fois que l'allocation dynamique est l'allocation sur le tas.
Les VLA sont déclarés sur la pile, comme toutes les autres variables locales (non statiques). Ces variables ont ce que la norme une "automatic storage duration".
a n'est pas alloué dynamiquement alors pourquoi tab le serait ?Code:
1
2
3
4
5 void f(int taille) { int a; int tab[taille]; }
Tout est dans ce qu'on met derrière le terme "dynamique". :)
Car la taille de a est connue à la compilation (statique) alors que tab uniquement à l'exécution (dynamique).
C'était exactement l'objet de ma question, ce n'est pas moi qui ait dit que c'était clairement défini, au contraire :)Citation:
Tout est dans ce qu'on met derrière le terme "dynamique". :)
Personnellement j'utilise "statique" pour ce qui est connu à la compilation, et "dynamique" pour ce qui est déterminé à l'exécution, indépendamment du tas ou de la pile. Mais ce n'est visiblement pas universel :aie:
Ta définition conduit donc à dire que a est alloué "statique automatique", tab en "dynamique automatique" et si la variable est allouée par un malloc en "dynamique dynamique(?)" et pour un variable déclarée static en "statique statique". Personne ne va comprendre. (je sais, je caricature ;))
Pour ta définition, tu te réfères au fait que la taille soit connue ou non à la compilation, alors que nous nous référons aux phases de création/destruction de l'objet (et tab est créé et détruit de la même façon que a ou taille). Le programmeur doit savoir quand ces évènements se produisent; il lui importe peu, du moment que le compilateur ne râle pas, que le compilateur connaisse ou non la taille de l'objet à la compilation.
Non je dirais probablement que tab est dynamique que ce soit un VLA ou un malloc. Le fait que tab soit automatiquement détruit à la sortie du scope n'enlève rien à son côté dynamique :)
Je me place principalement d'un point de vue de la programmation bien sûr : est-ce que la taille de la donnée que je veux allouer est connue ou non à la compilation ?Citation:
Pour ta définition, tu te réfères au fait que la taille soit connue ou non à la compilation, alors que nous nous référons aux phases de création/destruction de l'objet (et tab est créé et détruit de la même façon que a ou taille). Le programmeur doit savoir quand ces évènements se produisent; il lui importe peu, du moment que le compilateur ne râle pas, que le compilateur connaisse ou non la taille de l'objet à la compilation.
Et tab n'est pas créé de la même façon que a sur ce point. Le VLA remplace les malloc/free dans pas mal de cas ou le programmeur associe "la taille mon tableau est dépendente du contexte" à "j'ai besoin de faire une allocation dynamique DONC un malloc".
Bon bref, c'était juste une discussion de vocabulaire, merci des éclaircissements.
PS: un collègue me fait remarquer que VLA est un "type" plus qu'un et que quand on écrit "void foo(int n, int bar[n]) {...}" rien n'empêche bar d'avoir été alloué par un malloc.
C'est parce qu'on ne passe jamais un tableau à une fonction, on passe un pointeur vers son premier élément. La convertion est implicite lors de l'appel à la fonction. Le cas d'un paramètre formel d'une fonction est d'ailleurs l'un des rares (si ce n'est le seul) où un tableau est rigoureusement identique à unCode:void foo(int n, int bar[n]) {...}
tableaupointeur.
C'est sans doute parce que tu parles d'une taille dynamique et non d'une allocation dynamique. Sinon que répondrais la question, sachant qu'en plus tu as dit que :Citation:
Le fait que tab soit automatiquement détruit à la sortie du scope n'enlève rien à son côté dynamique
Dans le code suivant, l'allocation est-elle dynamiqueCitation:
est-ce que la taille de la donnée que je veux allouer est connue ou non à la compilation ?
malgrébien que la taille est connue à la compilation ?
Code:int *p = malloc(4);
Il y a peut-être aussi une dimension historique, ce que tu sous-entends dans cette phrase : avant, taille variable voulait forcément dire malloc avec une allocation dynamique. Maintenant (le C99 est pas si jeune, mais il a dû mal à sortir....), une taille variable ne veut plus forcément dire "allocation dynamique" puisque les VLA sont alloués automatiquement.Citation:
"j'ai besoin de faire une allocation dynamique DONC un malloc"
J'imagine que tu voulais dire que tableau == pointeur. Je sais bien que les tableaux sont passés comme des pointeurs, je voulais souligner que VLA revêt une dimension différente de l'allocation.
Bien vu, j'appellerai ça "dynamique" mais c'est une vue déformée à force de faire du dev dans le compilo ;)Citation:
C'est sans doute parce que tu parles d'une taille dynamique et non d'une allocation dynamique. Sinon que répondrais la question, sachant qu'en plus tu as dit que :
Dans le code suivant, l'allocation est-elle dynamique malgré que la taille est connue à la compilation ?
Code:int *p = malloc(4);
Oui, certainement. D'ailleurs j'ai cru comprendre que le compilo Microsoft n'implémente pas C99 ?Citation:
Il y a peut-être aussi une dimension historique, ce que tu sous-entends dans cette phrase : avant, taille variable voulait forcément dire malloc avec une allocation dynamique. Maintenant (le C99 est pas si jeune, mais il a dû mal à sortir....), une taille variable ne veut plus forcément dire "allocation dynamique" puisque les VLA sont alloués automatiquement.