Allocation du memoir en c
Résolu/Fermé
anouar437
Messages postés
8
Date d'inscription
mardi 4 novembre 2008
Statut
Membre
Dernière intervention
3 janvier 2009
-
4 nov. 2008 à 00:52
anouar437 Messages postés 8 Date d'inscription mardi 4 novembre 2008 Statut Membre Dernière intervention 3 janvier 2009 - 4 nov. 2008 à 17:58
anouar437 Messages postés 8 Date d'inscription mardi 4 novembre 2008 Statut Membre Dernière intervention 3 janvier 2009 - 4 nov. 2008 à 17:58
A voir également:
- En informatique, les informations sont codées par des 0 et des 1, appelés bits. un bit correspond à un espace mémoire. parmi les séquences ci-dessous, lesquelles occupent le moins d'espace en mémoire ?
- Espace insécable word - Guide
- Code binaire : principe, codage, règles, symboles - Guide
- Le code ascii en informatique - Guide
- Winrar 64 bits windows 10 - Télécharger - Compression & Décompression
- Comment liberer de l'espace sur gmail - Guide
3 réponses
mamiemando
Messages postés
33361
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
15 novembre 2024
7 799
4 nov. 2008 à 01:16
4 nov. 2008 à 01:16
Qu'est ce qu'un void * ?
Un malloc alloue une zone mémoire dont la taille est passée en paramètre. Il retourne une adresse générique, c'est à dire un pointeur de type void *.
Lorsqu'on parle d'un pointeur p de type void * cela signifie qu'on ne sait pas de quel type est *p (alors que pour pour un plop_t *, p serait de type plop_t).
Pourquoi typer les pointeurs... puisque ce ne sont jamais que des adresses ?
Or comme tu le sais, les pointeurs ne sont pas toujours simples à utiliser en C et on se mélange rapidement, donc quand on peut typer les pointeurs, on ne s'en prive pas.
Ainsi en cas de mauvaise utilisation, le compilateur peut lever des warnings pour dire qu'on manipule sur une instruction des pointeurs hétérogènes.
Le rôle du (int *) que tu ne comprend pas consiste à caster le pointeur, c'est à dire à écraser ton type (ici void *) par un autre (int *).
En soit tu pourrais ne pas faire le cast, car un malloc ne retourne jamais qu'une adresse. Mais si tu ne fais pas le cast, le compilateur te dira que tu essayes d'affecter un void * dans un int *, et sous-entendra ainsi que soit tu programmes comme un sale, soit que tu t'es craqué.
Conclusion : avec un malloc on fait le cast pour éviter ce genre de warning.
malloc et free
Ceci dit, le fait de caster un pointeur ne te dispense en aucun de libérer la mémoire allouée par le malloc dès que tu n'en a plus besoin avec l'instruction free. Exemple :
malloc, calloc, realloc
Note qu'il existe d'autres fonctions d'allocation (par exemple calloc) qui comme malloc retournent un pointeur générique (void *) qu'il faut caster.
Bonne chance
Un malloc alloue une zone mémoire dont la taille est passée en paramètre. Il retourne une adresse générique, c'est à dire un pointeur de type void *.
Lorsqu'on parle d'un pointeur p de type void * cela signifie qu'on ne sait pas de quel type est *p (alors que pour pour un plop_t *, p serait de type plop_t).
Pourquoi typer les pointeurs... puisque ce ne sont jamais que des adresses ?
Or comme tu le sais, les pointeurs ne sont pas toujours simples à utiliser en C et on se mélange rapidement, donc quand on peut typer les pointeurs, on ne s'en prive pas.
Ainsi en cas de mauvaise utilisation, le compilateur peut lever des warnings pour dire qu'on manipule sur une instruction des pointeurs hétérogènes.
Le rôle du (int *) que tu ne comprend pas consiste à caster le pointeur, c'est à dire à écraser ton type (ici void *) par un autre (int *).
En soit tu pourrais ne pas faire le cast, car un malloc ne retourne jamais qu'une adresse. Mais si tu ne fais pas le cast, le compilateur te dira que tu essayes d'affecter un void * dans un int *, et sous-entendra ainsi que soit tu programmes comme un sale, soit que tu t'es craqué.
Conclusion : avec un malloc on fait le cast pour éviter ce genre de warning.
malloc et free
Ceci dit, le fait de caster un pointeur ne te dispense en aucun de libérer la mémoire allouée par le malloc dès que tu n'en a plus besoin avec l'instruction free. Exemple :
#include <stdlib.h> int main(){ int *p = (int *)malloc(10*sizeof(int)); // j'alloue une plage de 10 entiers unsigned i; for(i=0;i<10;++i) p[i] = i; free(p); // quand j'ai fini d'utiliser p, je le libère return 0; }
malloc, calloc, realloc
Note qu'il existe d'autres fonctions d'allocation (par exemple calloc) qui comme malloc retournent un pointeur générique (void *) qu'il faut caster.
Bonne chance
Marco la baraque
Messages postés
996
Date d'inscription
vendredi 9 mai 2008
Statut
Contributeur
Dernière intervention
5 novembre 2009
329
4 nov. 2008 à 01:18
4 nov. 2008 à 01:18
Bonsoir,
Normalement il vaut mieux utiliser ceci :
int * p = (int*) malloc(n * sizeof(int));
En fait malloc retourne une valeur de type void*. Pour stocker sa valeur de retour dans un int*, il faut faire ce qu'on appelle un 'cast'. C'est-à-dire qu'on va formater la valeur de retour.
Dans ce cas, les pointeurs étant des adresses, même si tu ne castes pas explicitement, tu n'auras pas trop de problème (juste des warnings à la compilation), car quelque soit le type de données, un pointeur est stocké (sur la plupart des architecture) sur 32bits.
Pour te donner un exemple de cast plus pertinent, tu as :
double a = 1.4;
int b = (int) a; //b = 1
Ici, si tu ne mets pas le cast explicite, tu vas avoir une erreur de compilation (un double est stocké sur 64bits, et un int sur 32bits, donc si tu ne le dis pas explicitement tu as une erreur).
C est fortement typé, ce qui signifie qu'il vaut toujours mieux effectuer un cast explicite quand tu as besoin. Par exemple si tu fais :
int a = 2;
short b = a;
Ca risque fort de marcher (même si tu as un warning). C aime bien qu'on déclare et respecte bien les types des données (d'où le cast de void* en int*).
Cordialement,
Normalement il vaut mieux utiliser ceci :
int * p = (int*) malloc(n * sizeof(int));
En fait malloc retourne une valeur de type void*. Pour stocker sa valeur de retour dans un int*, il faut faire ce qu'on appelle un 'cast'. C'est-à-dire qu'on va formater la valeur de retour.
Dans ce cas, les pointeurs étant des adresses, même si tu ne castes pas explicitement, tu n'auras pas trop de problème (juste des warnings à la compilation), car quelque soit le type de données, un pointeur est stocké (sur la plupart des architecture) sur 32bits.
Pour te donner un exemple de cast plus pertinent, tu as :
double a = 1.4;
int b = (int) a; //b = 1
Ici, si tu ne mets pas le cast explicite, tu vas avoir une erreur de compilation (un double est stocké sur 64bits, et un int sur 32bits, donc si tu ne le dis pas explicitement tu as une erreur).
C est fortement typé, ce qui signifie qu'il vaut toujours mieux effectuer un cast explicite quand tu as besoin. Par exemple si tu fais :
int a = 2;
short b = a;
Ca risque fort de marcher (même si tu as un warning). C aime bien qu'on déclare et respecte bien les types des données (d'où le cast de void* en int*).
Cordialement,
anouar437
Messages postés
8
Date d'inscription
mardi 4 novembre 2008
Statut
Membre
Dernière intervention
3 janvier 2009
4 nov. 2008 à 01:30
4 nov. 2008 à 01:30
merci pr votre aide
j'ai bien compris
j'ai bien compris
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 841
4 nov. 2008 à 01:33
4 nov. 2008 à 01:33
D'accord pour le double en int. Car il y a perte de précision. Mais le cast entre void* et type* est inutile car implicite.Et cela est même déconseillé. A moins, d'utiliser les tous premiers compilateurs. Mais bon, cas très rare. Voir la remarque 3 pour plus de détails.
Cdlt
Cdlt
anouar437
Messages postés
8
Date d'inscription
mardi 4 novembre 2008
Statut
Membre
Dernière intervention
3 janvier 2009
4 nov. 2008 à 16:05
4 nov. 2008 à 16:05
mamiemando, svp j'ai testé ce programme
#include <stdio.h>
#include <stdlib.h>
void main()
{
int* p;
unsigned i;
p=malloc(10*sizeof(int));
for(i=0;i<10;++i)
{
p[i] = i;
printf("%d",p[i]);
}
free(p);
system("PAUSE");
}
avec ou sans (int*) sa marche bien
est ce que c facultatif ou koi ??
#include <stdio.h>
#include <stdlib.h>
void main()
{
int* p;
unsigned i;
p=malloc(10*sizeof(int));
for(i=0;i<10;++i)
{
p[i] = i;
printf("%d",p[i]);
}
free(p);
system("PAUSE");
}
avec ou sans (int*) sa marche bien
est ce que c facultatif ou koi ??
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 841
4 nov. 2008 à 16:26
4 nov. 2008 à 16:26
Relis la conversation, tu comprendras mieux pourquoi c'est facultatif, voir même déconseillé. A moins de vouloir utiliser des compilateurs très anciens.
Cdlt
Cdlt
anouar437
Messages postés
8
Date d'inscription
mardi 4 novembre 2008
Statut
Membre
Dernière intervention
3 janvier 2009
>
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
4 nov. 2008 à 17:16
4 nov. 2008 à 17:16
fiddy svp ce que j'ai compris c qu'il est préférable de mettre (int*)
une autre chose, j'essayé d'utilider malloc sans appelle à la bebliothèque stdlib.h et sa march juste avec #include <stdio.h>
une autre chose, j'essayé d'utilider malloc sans appelle à la bebliothèque stdlib.h et sa march juste avec #include <stdio.h>
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 841
>
anouar437
Messages postés
8
Date d'inscription
mardi 4 novembre 2008
Statut
Membre
Dernière intervention
3 janvier 2009
4 nov. 2008 à 17:31
4 nov. 2008 à 17:31
Salut,
Visiblement, t'as pas très bien compris.
J'essaie de faire au plus clair une dernière fois.
Si tu n'obtiens pas de messages d'erreurs ou d'avertissements en utilisant malloc et compagnie sans avoir inclue stdlib.h c'est que tu n'as pas mis de bonnes options (il est préférable d'afficher tous les avertissements), ou alors que ton compilateur ne respecte pas la norme.
Quoiqu'il en soit, lorsque tu utilises malloc, tu dois inclure stdlib.h. Sinon le retour du prototype de malloc est un int au lieu du vrai void*. C'est d'ailleurs comme ça que le compilateur doit s'apercevoir de l'oubli de la bibliothèque.
De plus, les compilateurs respectant la norme savent parfaitement bien que le cast void* en type* est implicite. Donc pas besoin de caster. Le compilateur s'en chargera tout seul.
Si tu cast quand même, il est possible que (cela dépend du compilateur) tu ne reçois pas d'avertissements. Donc à proscrire.
Pour résumer :
Pour utiliser malloc, pas de cast et on inclue stdlib.h. A moins de vouloir que ça compile sur les vieux compilateurs ne respectant pas la norme).
Visiblement, t'as pas très bien compris.
J'essaie de faire au plus clair une dernière fois.
Si tu n'obtiens pas de messages d'erreurs ou d'avertissements en utilisant malloc et compagnie sans avoir inclue stdlib.h c'est que tu n'as pas mis de bonnes options (il est préférable d'afficher tous les avertissements), ou alors que ton compilateur ne respecte pas la norme.
Quoiqu'il en soit, lorsque tu utilises malloc, tu dois inclure stdlib.h. Sinon le retour du prototype de malloc est un int au lieu du vrai void*. C'est d'ailleurs comme ça que le compilateur doit s'apercevoir de l'oubli de la bibliothèque.
De plus, les compilateurs respectant la norme savent parfaitement bien que le cast void* en type* est implicite. Donc pas besoin de caster. Le compilateur s'en chargera tout seul.
Si tu cast quand même, il est possible que (cela dépend du compilateur) tu ne reçois pas d'avertissements. Donc à proscrire.
Pour résumer :
Pour utiliser malloc, pas de cast et on inclue stdlib.h. A moins de vouloir que ça compile sur les vieux compilateurs ne respectant pas la norme).
anouar437
Messages postés
8
Date d'inscription
mardi 4 novembre 2008
Statut
Membre
Dernière intervention
3 janvier 2009
>
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
4 nov. 2008 à 17:58
4 nov. 2008 à 17:58
merci bcp pour votre attention c'est clair mnt
4 nov. 2008 à 01:26
Je ne suis pas vraiment d'accord avec toi. Le cast void* en type* est implicite. Donc pas besoin de le spécifier au compilateur. Le cast entre ces deux derniers était surtout utilisé avec les vieux compilateurs. Mais, aujourd'hui cela est plus dangereux qu'autre chose. Car comme tu dis le cast fera taire le compilateur et enlèvera donc le warning obtenu en oubliant d'inclure stdlib.h. Oups. Pas cool.
Et puis, les compilateurs connaissent les normes maintenant :). Et en plus, cela allège le code. :)
4 nov. 2008 à 01:48
En plus alléger un cast c'est vraiment gagne-petit (un quart de ligne...), alors je ne vois pas trop ce que ça gagne à part donner un code laid. Ça me fait penser aux gens qui ferment pas leur parenthèses en TI-basic en croyant que ça gagne de la place alors que c'est juste illisible :p
En plus, c'est important qu'il comprenne à quoi sert (et quand faire à bon escient) un cast, et le malloc est l'un des cas où il a vraiment du sens ^^
4 nov. 2008 à 10:29
J'ai jamais dit que ne pas mettre le cast faisait des Warning et je suis comme toi. Un programme doit se compiler sans warning. Sinon, je reformule ce que j'expliquais :
int *p=(int*)malloc(sizeof(int)*n); était obligatoire sur les premiers compilateurs K&R qui ne connaissaient pas bien les normes, donc ça date de longtemps. Maintenant les compilateurs respectent les normes et donc cast impliciement un void * en type*. Donc pas besoin de caster. Et, ne t'inquiète pas, le compilateur ne fera pas apparaître de warning. Jusque là, on pourrait donc penser qu'on a le choix entre caster ou pas.
Sauf que, le seul risque qu'il y a en utilisant malloc (sans compter les problèmes de gestion de la mémoire qui n'est pas un problème à proprement parler du compilateur), c'est l'oubli d'inclure la bibliothèque stdlib. Teste sans l'inclure, tu verras un joli warning, mais pas une erreur (ceci dépend du compilateur).
Or il se trouve que caster le malloc enlève cet avertissement. Voilà pourquoi c'est dangereux de caster le malloc. Caster le malloc empêche au compilateur de prévenir lorsque t'as oublié d'inclure ladite bibliothèque.
Donc, autant écrire : int *p=malloc(sizeof(int)*n). Le compilateur ne fera aucun warning et tout sera propre. Et en plus il t'avertira quant à l'oubli de stdlib.h.
4 nov. 2008 à 12:38
Donc là, l'oubli de stdlib se voit. Mais sinon effectivement, si on ne cast pas le malloc il n'y a pas (plus) de warning.
Merci pour tes précisions et bonne continuation
4 nov. 2008 à 14:09
Oui, car tu utilises un compilateur correct. Mais la version 3.3.6 par exemple ne voyait pas l'oubli de la bibliothèque. Et donc là, cela dépendra du compilateur car non prévu par la norme. Alors que si on ne cast pas, on se retrouve avec un le mauvais prototype de malloc (qui retourne un int au lieu du void*) et là la norme prévoit de te prévenir.