ton problème c'est pas forcément la fonction malloc, c'est plutôt l'opérateur sizeof.
La fonction malloc est hyper simple : un seul paramètre, la taille en char (=byte=octet pour simplifier) d'une zone mémoire qu'on voudrait avoir, et un seul retour un pointeur qui pointe soit nulle part (NULL) pour indiquer qu'il y a eu une erreur soit qui n'est pas NULL et pointe vers un endroit valide de la mémoire où tu pourras accéder à la taille indiquée bytes.
Ça tu l'as bien compris.
Passons maintenant à sizeof. Cet opérateur renvoie la taille de ce qu'on lui donne en paramètre. Par exemple avec le code :
#include <stdio.h>
int main(void)
{
short i=42;
short *p=&i;
printf("sizeof(short) = %zu\n", sizeof(short));
printf("sizeof(i) = %zu\n", sizeof(i));
printf("sizeof(p) = %zu\n", sizeof(p));
printf("sizeof(*p) = %zu\n", sizeof(*p));
return 0;
}
et tu vois que si tu donnes à sizeof directement le type short ou une variable de type short ou une variable de type pointeur sur short que tu déréférences en opérande alors le résultat est le même.
Dans le cas :
Liste *liste = malloc(sizeof(*liste));
sizeof prend ici comme opérande *liste, tu déréférences (en gros hein …) la variable liste qui est de type pointeur sur Liste et tu tombes donc sur un objet de type Liste dont tu prends la taille. C'est donc strictement équivalent à :
Liste *liste = malloc(sizeof(Liste));
d'une manière générale une ligne comme :
T *new=malloc( sizeof( *new ) );
sera toujours correcte car tu demandes d'allouer la mémoire qu'il faut pour stocker ce vers quoi pointera ta variable, quel que soit le type T. Le jour où tu refactores ton code, si T change tu n'as à le modifier qu'une fois au lieu de deux dans :
Et encore un autre malloc que je comprend pas qui va dans le sens du dernier:
Liste *liste = (Liste*)(malloc(sizeof(liste)).
La c'est comme-ci tu m'as mis devant mike tyson à l'age de c'est 18 ans .
donc pour résumé voici les deux malloc que je ne comprends rien:
Liste *liste = (Liste*)(malloc(sizeof(Liste)).
Liste *liste = malloc(sizeof(*liste));
MErci de l'aide
Attention à la casse !!! Liste ≠ liste …
le (Liste *) devant le malloc s'appelle un cast ou transtypage. C'est considéré comme une (hyper) mauvaise pratique que d'utiliser ça. Si ton compilo te pose des problèmes avec ça … alors c'est que tu compiles en C++ et non en C.
En effet pour comprendre tes 2 malloc() il faut voir à quoi correspond un élément de liste. Ce qu'il faut allouer c'est : - une zone qui contiendra le début de la liste, problème ce début est nommé avec le type 'Liste' dans ton exemple. - ensuite les éléments chaînés doivent avoir une forme :
struct Element
{
... ... ... les données de l'élement
struct Element* suivant;
};
C'est cet élément le plus important et tu ne l'a pas indiqué. Ensuite il faut allouer 2 choses l'entête de liste et chacun des éléments. Et donc la ligne
Liste *liste = malloc(sizeof(*liste)); // ici *liste est un objet
est bien correcte, on alloue une structure Liste et on va pointer dessus. *liste désigne ce qui est pointé par liste, on aurait pu écrire:
Liste *liste = malloc(sizeof(Liste)); // ici Liste est un type de donnée
personnellement, je préfère la première notation.
L'autre malloc() par contre est forcément une erreur:
Liste *liste = (Liste*)(malloc(sizeof(liste))
On alloue un objet de la taille de liste et on dit que liste pointe dessus. On alloue donc un pointeur alors qu'il faut à un moment allouer une zone pour mettre les objets de type Element. Mais coup de bol, *liste contient juste un pointeur et liste est un pointeur donc les 2 ont la même taille, mais cette ligne est fausse. Je pense que la ligne qui alloue un maillon est ailleurs dans le code, ça devrait ressembler à :
sera toujours correcte car tu demandes d'allouer la mémoire qu'il faut pour stocker ce vers quoi pointera ta variable, quel que soit le type T. Le jour où tu refactores ton code, si T change tu n'as à le modifier qu'une fois au lieu de deux dans :
C'est pas faux. Mais il t'arrivera plus souvent de changer de type que le nom d'une variable locale, enfin je te dis ça par expérience. Cette dernière écriture est aussi moins sujette aux erreurs et te permet de ne pas avoir à trop réfléchir. Par exemple dans un bout de code tu va écrire :
T *new=NULL;
bla bla bla ...
beaucoup plus bas ...
new = malloc( <ah mince c'est quoi encore le type de new ???
Alors que lorsque tu écris :
new = malloc( sizeof *new );
bah c'est forcément bon et tu n'as pas à remonter pour vérifier le type, ou avoir à débuger par la suite car tu t'es trompé de type etc …
Je comprends. il est plus problablr (d’après ton expérience) de changer de nom type de la strucutre que de nom de variable au sein de la structure.
Parfait. C'est noté.
malloc
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
En recherche d'emploi.