A chaque fois que je demande à un programmeur de m'expliquer l'interêt de l'allocation dynamique il me réponds "c'est par exemple quand tu ne sais pas la taille que va faire ton tableau lors de la compilation"
Je trouve cette explication totalement stupide car il suffit de definir la taille du tableau par une variable, par exemple X et de donner une valeur à X pendant le programme, donc dans ce cas l'allocation dynamique est totalement inutil ...
Ce que tu décris, c'est précisément l'allocation dynamique...
En C, il y a aussi une différence sémantique : une variable alloué dynamiquement (pas avec ta méthode cependant) est alloué sur le tas et non pas sur la pile et n'est donc pas désalloué lorsque la fonction où elle a été alloué se termine. Mais cette différence n'est pas valable pour tout les langages.
L'allocation dynamique, c'est tout simplement la solution pour n'utiliser que ce qu'on a besoin comme mémoire à un instant t, ni plus, ni moins. Tu ne vas pas utiliser un buffer de 65k avec un marqueur de fin si la structure fait généralement moins de 30 octets. Néanmoins, tu peux avoir des pics à 64k et dans ce cas, tu es obligé d'avoir la possibilité d'allouer cette taille de données. L'allocation dynamique sert à ça. Parce qu'on ne manipule pas toujours des données dont on maîtrise la longueur à l'écriture du programme.
dnob700
J'ai peur qu'il ne parle de déclarer des variables "à la Pascal" (taille fixe, marqueur de longueur en tête)...
pourtant l'allocation dynamique en C se fait avec Malloc et Free , ce que je décris la c'est juste en metant une variable a la place du nombre de case du tableau , et donner une valeur a x au cour du programme sans utiliser Malloc.
Ce que tu décris c'est quelque chose qui n'existe pas en C ANSI, mais qui a été introduit dans une norme plus récente du C. Donc avant ça, les gens n'avait pas le choix que d'utiliser malloc et free.
D'autre part, ce que tu décrit est bien de l'allocation dynamique, même si ça n'utilise pas malloc et free.
Et enfin, il reste de toutes manière pour malloc et free l'avantage (ou l'inconvénient, c'est selon) que je t'ai donné plus haut, que ça permet d'avoir des variables avec des portées plus longues que celle de la fonction où elles sont déclarées.
orangebud2 : et tu fais comment pour avoir ton tableau à partir de ta variable taille sans faire de malloc (ou équivalent)... tu alloues 1 Go de mémoire et tu pries pour ne jamais avoir besoin de plus ?
Je dis "tu", mais ça peut très bien être l'interpréteur/le compilateur qui s'occupe de cette tâche à ta place pour un langage «de haut niveau». Dans tous les cas, on finit toujours par appeler une routine «bas niveau» pour réserver en mémoire la place qu'occupera le tableau. Et là tu alloues la place dont tu as besoin à l'exécution (allocation dynamique). L'alternative est de définir une taille maximale (le 1 Go de tout à l'heure) et dans ce cas l'allocation peut se faire de façon statique (mais ton programme bouffera 1 Go de RAM à l'exécution...).
Bref : «l'allocation dynamique est totalement inutil ... »
c'est la gestion explicite (au sens où tu dois ajouter du code exprès pour ça) de l'allocation dynamique des données qui est souvent inutile en fait. ![]()
la gestion de la mémoire et l'allocation dynamique font partie de l'optimisation
Bah en fait il suffit de demander à l'utilisateur la valeur de x avec un scanf ...
C'est surtout une provocation puisque j'utilise toujours l'allocation dynamique en c++ avec new et delete, mais le truc qui m'enerve c'est que l'exemple que donne les gens a chaque fois c'est le coup du tableau, alors que c'est faisable sans malloc
orangebud2 : relis la fin de mon message...
Tu es en train de confondre un concept (l'allocation dynamique) avec la syntaxe là (le malloc du C en l'occurence). ![]()
"c'est le coup du tableau, alors que c'est faisable sans malloc "
Oui, on t'as dit 36 fois qu'avec ou sans malloc, c'est de toutes manières de l'allocation dynamique.
Chris_27 : cette syntaxe :
int f(int n)
{
int table[n];
...
}
est valable en C99, et gcc accepte même des choses plus violentes (n'importe quoi en fait comme taille pour le tableau, et pas seulement l'un des arguments de la fonction).
au sujet de malloc et free, tu as le probleme de la reallocation.
Si tu ne sais pas combien tu vas avoir d'element dans ta structure de donne avant qu'on te les donnes, il va falloir changer la taille du tableau.
et tu ne peux pas changer la taille d'un tableau declare avec sa taille. Tu es oblige d'en delcarer un nouveau et de copier les donnes
mais avec les problemes de portesm tu perds la memoire alloue au premier.
dnob700 : merci pour l'info (même si je dois avouer que ce n'est pas très réjouissant vu les bogues que je verrais en TP de C dans quelques années à cause de ça
)
Si j'ai bien compris, l'exemple qui suit est réalisable ?
~$ cat test.c
int n = 10;
int tab[n];
int main (void) {
return 0;
}
~$ gcc -c test.c
test.c:2: error: variably modified ‘tab’ at file scope
Pourtant gcc me dit le contraire ^^°
non, c'est ca que tu peux faire:
$ cat toto.c
int main()
{
int n=10;
{
char toto[n];
}
return 0;
}
c'est compilable avec l'option --std=c99
(la norme C99 est la norme la plus récente du langage C, cependant n'étant pas encore parfaitement implémentée par gcc, les fichiers sources se compilent par défaut en C90)
il est aussi possible de faire de la réallocation, par ex:
int i, taille = 2 ; // taille initiale du tableau
int t[taille] ;
for ( i = 0 ; i < taille ; i ++ ) t[i] = i + 1 ;
taille = 5 ; // modifie dynamiquement la taille du tableau
for ( int j = i; j < taille; j ++ ) t[j] = j + 1 ;
for ( int i = 0 ; i < taille ; i ++ )
printf("%d\t", t[i]); printf("\n"); // affiche '1 2 3 4 5'
voir cette page: http://nicolasj.developpez.com/articles/c99/ pour un aperçu de C99
En effet godrik, ça fonctionne.
Cependant, je n'ai jamais utilisé cette syntaxe. Ça signifie quoi les "sous-accolades" ?
un nouveau block, ca permet de changer la portee des variables.
void fnct()
{
int a=2;
{a = 3;}
//ici a vaut 3
{int a = 12;
//ici a vaut 12
}
//ici a vaut 3
}
Pour pouvoir utiliser la char toto[n], il faut que n soit declare en dehors de la porte actuelle.
Ok merci.
Mais du coup, avec ça si on fait pas gaffe on peut vite se retrouver dans des situations périlleuses.
Je comprends pourquoi ils nous montrent pas ça en cours de C. Ça doit être bien sympathique à débugger ![]()
C'est pratique. Si tu as besoin de tableau de different type, ou de taille differente, ou meme juste pour changer son nom
tu peux faire
void fnct()
{
int n =42;
{
char foo[n];
//code
}
{
char bar[n];
//code
}
}
Les deux tableaux n'existent pas en memoire en meme temps (enfin ton compilateur peut faire ca). Potentiellement le compilo peut recycler la memoire de l'un pour l'autre, ce qui permet de "changer" le nom tableau. C'est mieux qu'avoir un buf et s'en servir pour 14 choses differentes.
iznoroot : jamais entendu parler de cette réallocation. Je crois que tu as deux jours de retard sur les poissons d'avrils ...