Tableau dynamique [C] - C - Programmation
Marsh Posté le 05-01-2005 à 11:40:23
arnaudm57 a écrit : Salut à tous, |
Tu devras sûrement utiliser la fonction malloc().
Bon maintenant à toi de chercher comment faire !
Marsh Posté le 05-01-2005 à 11:51:54
Hello !
Pour un tableau de doubles par exemple, soit tu fais :
- alloc dynamique :
// déclaration du pointeur sur la première case du tableau
double * tab;
// allocation des cases
tab=(double *)malloc(NbElements*sizeof(double));
// acces à la case i
tab[i] ou *(tab+i)
// acces au pointeur de la case i
&tab[i] ou (tab+i)
// libération mémoire après utilisation
free(tab);
- allocation statique
// déclaration du tableau de doubles de taille fixée
double tab[NbElements];
// allocation des cases (pas besoin)
// acces à la case i
tab[i] ou *(tab+i)
// acces au pointeur de la case i
&tab[i] ou (tab+i)
// libération mémoire après utilisation (pas besoin)
Voili voili !
Marsh Posté le 05-01-2005 à 12:39:50
allawos a écrit : |
pourquoi cast tu ? qu'est-ce qui se passe si tab n'est plus un pointeur de double mais de float ? N'oublie pas de gérer le cas ou malloc retourne NULL. N'oublie pas '#include <stdlib.h>'
Marsh Posté le 05-01-2005 à 13:07:14
c'est OBLIGATOIRE de faire un cast comme ça si il y a incompatibilité en le cast et la variable de réception il y aura probablement un warning du compilo (même si ça dépend du compilo).
Marsh Posté le 05-01-2005 à 13:22:17
dreameddeath a écrit : c'est OBLIGATOIRE de faire un cast comme ça si il y a incompatibilité en le cast et la variable de réception il y aura probablement un warning du compilo (même si ça dépend du compilo). |
Pas en C (ou alors avec un très vieux compilateur qui ne connait pas 'void').
http://mapage.noos.fr/emdel/notes.htm#malloc
Marsh Posté le 05-01-2005 à 14:11:33
je n'ai pas voulu dire qu'il est obligatoire d'un point de vue syntaxique mais plutôt d'un point de vue sureté du code (vérication du compilateur de la compatibilité du cast et de la variable de destination)
Marsh Posté le 05-01-2005 à 14:17:31
dreameddeath a écrit : je n'ai pas voulu dire qu'il est obligatoire d'un point de vue syntaxique mais plutôt d'un point de vue sureté du code (vérication du compilateur de la compatibilité du cast et de la variable de destination) |
Bah non, justement.
Le compilo ne vérifie rien si tu castes un pointeur en un autre. Alors qu'en ne mettant rien, il va vérifier justement si tu fais des bétises ou pas (au niveau de la constness entre autres, et de void*).
Marsh Posté le 05-01-2005 à 14:23:32
il va vérifier quoi sans cast?
malloc rendant un (void *) comment le compilo sait ce que ça représente réellement? Alors qu'en "castant", tu dis explicitement ce que représente ce que tu a alloué, et ensuite lors de l'affectation le compilo peut comparer. le void * n'est qu'un fourre tout pas beau !
Marsh Posté le 05-01-2005 à 14:23:51
Lam's a écrit : Bah non, justement. |
+1
Un cast ça sert à "forcer" le type. Donc le compilo il ferme sa gueule dans ce cas.
Il n'y a pas besoin d'utiliser un cast lorsque le type de départ est void * !
Marsh Posté le 05-01-2005 à 14:34:46
pour moi il ne doit y avoir aucun transtypage implicite car ça peut être dangereux.
Par exemple avec le code :
Code :
|
tu te dis que double n'est pas le bon type mais c'est mieux un int ou autre (evolutivité du code), tu remplace double par int mais tu oublie certains endroits :
Code :
|
tu recompiles et paf t'a un message alors que si tu mets pas le cast tu n'as rien ...
Marsh Posté le 05-01-2005 à 14:48:00
dreameddeath a écrit : pour moi il ne doit y avoir aucun transtypage implicite car ça peut être dangereux. |
C'est parce que tu mets en oeuvre des pratiques dangereuses. Le transtypage ne fait qu'ajouter à la confusion générale...
Citation :
|
Les pratiques dangereuses sont:
- 100 lignes entre la définition d'un objet et son utilisation
- utilisation du type pour déterminer la taille.
Si tu ne mets pas de transtypage, le code est toujours correct, à condition d'utilises non pas le type, (qui peut changer, comme tu l'as fait remarqué, et c'est effectivement vrai sur le terrain) mais le pointeur pour déterminer la taille. La maintenance s'en trouve simplifiée et le code est plus sûr. D'autre part, il faut appliquer au maximum le principe de réduction de la portée des objets et des fonctions.
La bonne pratique est celle-ci
int *tab = malloc (NbElements * sizeof *tab); |
Je rappelle :
http://mapage.noos.fr/emdel/notes.htm#malloc
et j'ajoute:
http://mapage.noos.fr/emdel/notes.htm#portee
Marsh Posté le 05-01-2005 à 14:49:40
d'où ma deuxième question : tu fais quoi si tab n'est plus un double * ? avec ton usage de malloc, tu te fais avoir.
Marsh Posté le 05-01-2005 à 14:52:29
une petite question en passant, en parlant de stdlib, y sort d'ou le malloc qui oblige à caster quand on inclut pas stdlib ?
Marsh Posté le 05-01-2005 à 14:55:19
de nulle part. En C, les convertion void* <-> T* sont implicites car sures et bien définies.
edit du message précédent : crammé
Marsh Posté le 05-01-2005 à 14:59:38
oui mais pq cette différence de comportement quand on inclut pas stdlib ?
Marsh Posté le 05-01-2005 à 14:59:43
push a écrit : une petite question en passant, en parlant de stdlib, y sort d'ou le malloc qui oblige à caster quand on inclut pas stdlib ? |
Parce que le programmeur neuneu de base croit qu'avec un cast il va corriger tous ses problèmes. Ce genre d'idée reçue a la vie longue et doit être combattue avec la dernière énergie. (Où est mon lance flammes)
La vérité est que que si il n'y a pas de prototype visible pour malloc() (qui ne retourne pas int, mais void*), le comportement est indéterminé (int dans un pointeur, ça le fait pas) et le cast ne corrige rien. Il faut donc obligatoirement inclure <stdlib.h>, et regler son compilateur correctement pour qu'il détecte l'absence de prototype.
Marsh Posté le 05-01-2005 à 15:00:14
je ne comprends pas ta remarque Taz? qu'entends tu exactement par : "si tab n'est plus un double *" ?
EDIT : oublie la question Taz j'ai rien dis ...
Marsh Posté le 05-01-2005 à 15:11:17
push a écrit : |
Oui, et ça ne compile pas. Pas dangereux. Code Corrigé.
Marsh Posté le 05-01-2005 à 15:37:53
Il reste encore la méthode alloca.
C'est pareil qu'un tableau statique de taille variable, mais ca s'ecrit comme un malloc.
Par contre je ne sais si c'est disponible sur toutes les plateformes... (brk doit l'être donc...)
Marsh Posté le 05-01-2005 à 15:42:02
rolphin a écrit : |
Ouille non. C'est pareil qu'un tableau en variable locale. Et comme le C99 permet désormais de faire des VLA, il n'y a plus trop de raison de l'utiliser. Déjà qu'il n'y en avait pas des masses avant: portée du tableau limitée à la fonction courante, taille limitée à la taille de pile disponible (et même pas forcément la taille de pile maximale), appel non portable, etc.
Marsh Posté le 06-01-2005 à 21:25:15
rolphin a écrit : Il reste encore la méthode alloca. |
Alloca n'alloue rien dans le tas (donc ca n'a pas rapport avec brk ). Ca ecrit dans ta pile et il est "free" en sorti de fonction comme une variable locale. Alloca ca poutre
Marsh Posté le 05-01-2005 à 11:03:49
Salut à tous,
J'aurais une petite question à vous poser concernant les tableaux dynamiques en C.
A partir d'une variable que l'on saisi à l'intérieur d'un programme : nombre par exemple, je souhaiterais créer un tableau ayant pour taille le "nombre" que l'on a saisi dans le programme.
Merci de votre aide