Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Question honteuse

27 réponses
Avatar
Stephane Legras-Decussy
bonjour,

j'ai honte poser une question aussi basique
mais je ne dois pas avoir les yeux en face des trous
et je ne comprend pas ce qui ne va pas depuis plusieures heures :

#include <stdio.h>
#include<conio.h>
#include<stdlib.h>


typedef struct
{
int nbr;

}AA;

void init(AA *aa)
{ aa= (AA*)malloc(sizeof(AA));

}


int main(int argc, char *argv[])
{ AA *aa=NULL;

// init(aa); // (1)

aa= (AA*)malloc(sizeof(AA)); // (2)

aa->nbr=10; // (3)

printf("%d\n",aa->nbr);

getch();

free(aa);

return 0;
}


si j'écris la ligne (2), tout va bien, si je remplace par la ligne (1) alors
le prog crash en ligne (3).

pourquoi ??? ça m'énerve de pas trouver...

10 réponses

1 2 3
Avatar
Eric Levenez
Le 23/03/05 22:43, dans <4241e2a3$0$2782$, « Stephane
Legras-Decussy » a écrit :

#include <stdio.h>
#include<conio.h>


Pas standard

#include<stdlib.h>


typedef struct
{
int nbr;

}AA;

void init(AA *aa)
{ aa= (AA*)malloc(sizeof(AA));


Cast inutile

}


int main(int argc, char *argv[])
{ AA *aa=NULL;

// init(aa); // (1)

aa= (AA*)malloc(sizeof(AA)); // (2)

aa->nbr; // (3)

printf("%dn",aa->nbr);

getch();


Pas standard

free(aa);

return 0;
}



Tu passes à init la valeur de aa, donc NULL. Cette fonction n'a aucun moyen
de retourner la nouvelle valeur de aa. Il faut donc passer l'adresse de la
variable aa et init doit modifier cette valeur :

#include <stdio.h>
#include <stdlib.h>

typedef struct {
int nbr;
} AA;

void init(AA **aa)
{
*aa = malloc(sizeof(AA));
}

int main(void)
{
AA *aa;

init(&aa);
aa->nbr = 10;
(void)printf("%dn", aa->nbr);
free(aa);
return 0;
}

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.

Avatar
Pierre Maurette
[...]
Tu passes à init la valeur de aa, donc NULL. Cette fonction n'a aucun moyen
de retourner la nouvelle valeur de aa. Il faut donc passer l'adresse de la
variable aa et init doit modifier cette valeur :
[...]

Ou alors:

AA* init(void){return (AA *) malloc(sizeof(AA));}

/* ..... */

aa = init();

--
Pierre

Avatar
Eric Levenez
Le 23/03/05 22:58, dans <4241e669$0$5353$, « Pierre
Maurette » a écrit :

[...]
Tu passes à init la valeur de aa, donc NULL. Cette fonction n'a aucun moyen
de retourner la nouvelle valeur de aa. Il faut donc passer l'adresse de la
variable aa et init doit modifier cette valeur :
[...]

Ou alors:

AA* init(void){return (AA *) malloc(sizeof(AA));}

/* ..... */

aa = init();


Oui, mais toujours sans le cas (AA *).

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Anthony
"Stephane Legras-Decussy" a écrit

bonjour,


Bonsoir,

j'ai honte poser une question aussi basique


Il ne faut jamais avoir honte ! :-)

[...]

void init(AA *aa)
{
aa= (AA*)malloc(sizeof(AA));
}


init() recoit un pointeur sur une structure AA. Elle modifie ce pointeur
puis elle retourne. Mais cette modification est perdue. C'est comme avec un
entier et un niveau d'indirection de moins.

void init(int aa)
{
aa = 42;
}

int main(void) {
int aa = 0;
init(aa);
printf("%dn", aa);
}

Ce programme n'affichera jamais 42.
C'est pareil si on met un niveau d'indirection de plus. Donc deux solutions
:

void init(AA** aa)
{
aa = malloc(sizeof(AA));
}

ou bien

AA* init(void)
{
return malloc(sizeof(AA));
}

si j'écris la ligne (2), tout va bien, si je remplace par la ligne (1)
alors
le prog crash en ligne (3).


Et le fait qu'il crashe en ligne 3 était dû au fait que aa valait NULL.
Etant donné que aa est NULL, aa->nbr crash lamentablement.

Avatar
Pierre Maurette
Le 23/03/05 22:58, dans <4241e669$0$5353$, « Pierre


[...]

Tu passes à init la valeur de aa, donc NULL. Cette fonction n'a aucun moyen
de retourner la nouvelle valeur de aa. Il faut donc passer l'adresse de la
variable aa et init doit modifier cette valeur :


[...]
Ou alors:

AA* init(void){return (AA *) malloc(sizeof(AA));}

/* ..... */

aa = init();



Oui, mais toujours sans le cas (AA *).
Je ne comprends pas... (fatigue ?)

--
Pierre



Avatar
Stephane Legras-Decussy
Eric Levenez a écrit dans le message :
BE67A3C6.310DE%
void init(AA **aa)


arf.... merçi pour toutes les réponses...

comme quoi même avec quelques dizaines de milliers
de ligne de C derrière soit, on peut quand même passer
à coté...

je vous dis pas depuis combien de temps ça me bloquait...
:-(

Avatar
cedric
Pierre Maurette wrote:
Oui, mais toujours sans le cas (AA *).


Je ne comprends pas... (fatigue ?)


sans le casT


Avatar
cedric
Stephane Legras-Decussy wrote:
je vous dis pas depuis combien de temps ça me bloquait...


Y'a des jours comme ça où le cerveau veut pas s'y mettre...

Avatar
Pierre Maurette
Pierre Maurette wrote:

Oui, mais toujours sans le cas (AA *).



Je ne comprends pas... (fatigue ?)



sans le casT
Merci ...

(j'ai donné mes raisons certainement discutables d'utiliser le cast du
malloc())
--
Pierre



Avatar
Eric Levenez
Le 24/03/05 8:13, dans <4242689e$0$859$, « cedric »
a écrit :

Pierre Maurette wrote:
Oui, mais toujours sans le cas (AA *).


Je ne comprends pas... (fatigue ?)


sans le casT


Oui, désolé, j'avais oublié le t. :-)

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.



1 2 3