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

1 code, 2 compilation, 2 comportements différents

8 réponses
Avatar
dieb
Bonsoir,

Lorsque je compile ce code sur 2 machines différentes (a et b)
(GNU/Linux Debian pour info) et sans aucune erreur, sur l'une (a) le
binaire résultant s'éxécute parfaitement, et sur l'autre (b) j'ai un
segfault (sur l'affectation gblconf->single_user = 0; ).
Si je prend le binaire de la première machine (a) que je le copie sur
(b), il s'exécute bien également.
Je ne peux pas croire qu'il s'agisse que d'un problème de compilateur.
J'ai certainement fais une bourde plus grosse que moi, mais elle ne me
saute pas aux yeux... Quelqu'un pourrait me l'indiquer?


#include <stdlib.h>

struct conf
{
unsigned int single_user;
};

int
main (void)
{
struct conf *gblconf;

gblconf->single_user = 0;

exit (EXIT_SUCCESS);
}



Merci de votre aide

8 réponses

Avatar
Nicolas Favre-Felix
dieb wrote:
Bonsoir,

Lorsque je compile ce code sur 2 machines différentes (a et b)
(GNU/Linux Debian pour info) et sans aucune erreur, sur l'une (a) le
binaire résultant s'éxécute parfaitement, et sur l'autre (b) j'ai un
segfault (sur l'affectation gblconf->single_user = 0; ).
Si je prend le binaire de la première machine (a) que je le copie sur
(b), il s'exécute bien également.
Je ne peux pas croire qu'il s'agisse que d'un problème de compilateur.
J'ai certainement fais une bourde plus grosse que moi, mais elle ne me
saute pas aux yeux... Quelqu'un pourrait me l'indiquer?


#include <stdlib.h>

struct conf
{
unsigned int single_user;
};

int
main (void)
{
struct conf *gblconf;

gblconf->single_user = 0;

exit (EXIT_SUCCESS);
}



Merci de votre aide


Le pointeur n'est pas initialisé et pointe dans l'espace. Il faut
allouer la mémoire.

struct conf *gblconf;
gblconf = malloc(sizeof(struct conf));
gblconf->single_user = 0;

Il est étonnant que ça fonctionne, d'ailleurs.

Nicolas.

Avatar
Emmanuel Delahaye
dieb wrote on 20/04/05 :
Lorsque je compile ce code sur 2 machines différentes (a et b) (GNU/Linux
Debian pour info) et sans aucune erreur, sur l'une (a) le binaire résultant
s'éxécute parfaitement, et sur l'autre (b) j'ai un segfault (sur
l'affectation gblconf->single_user = 0; ).


Typique d'un comportement indéfini.

Si je prend le binaire de la première machine (a) que je le copie sur (b), il
s'exécute bien également.
Je ne peux pas croire qu'il s'agisse que d'un problème de compilateur. J'ai
certainement fais une bourde plus grosse que moi, mais elle ne me saute pas
aux yeux... Quelqu'un pourrait me l'indiquer?

#include <stdlib.h>

struct conf
{
unsigned int single_user;
};

int
main (void)
{
struct conf *gblconf;

gblconf->single_user = 0;


Déréférencement d'un pointeur non initialisé : Comportement indéfini.
Il peut arriver n'importe quoi...


exit (EXIT_SUCCESS);
}


Et si tu apprenais à ton compilateur à te dire la vérité ?

main.c:20: warning: `gblconf' might be used uninitialized in this
function

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Mal nommer les choses c'est ajouter du malheur au
monde." -- Albert Camus.

Avatar
Hamiral
struct conf *gblconf;

gblconf->single_user = 0;


Tu es en retard de 19 jours ...

Avatar
dieb
Nicolas Favre-Felix wrote:
dieb wrote:

Bonsoir,

Lorsque je compile ce code sur 2 machines différentes (a et b)
(GNU/Linux Debian pour info) et sans aucune erreur, sur l'une (a) le
binaire résultant s'éxécute parfaitement, et sur l'autre (b) j'ai un
segfault (sur l'affectation gblconf->single_user = 0; ).
Si je prend le binaire de la première machine (a) que je le copie sur
(b), il s'exécute bien également.
Je ne peux pas croire qu'il s'agisse que d'un problème de compilateur.
J'ai certainement fais une bourde plus grosse que moi, mais elle ne me
saute pas aux yeux... Quelqu'un pourrait me l'indiquer?


#include <stdlib.h>

struct conf
{
unsigned int single_user;
};

int
main (void)
{
struct conf *gblconf;

gblconf->single_user = 0;

exit (EXIT_SUCCESS);
}



Merci de votre aide



Le pointeur n'est pas initialisé et pointe dans l'espace. Il faut
allouer la mémoire.

struct conf *gblconf;
gblconf = malloc(sizeof(struct conf));
gblconf->single_user = 0;

Il est étonnant que ça fonctionne, d'ailleurs.

Nicolas.


Arg!!! mais bien sur!!
J'ai vraiment besoin de vacances!

Merci beaucoup pour cette aimable réponse.

Vincent


Avatar
Stephane Legras-Decussy
dieb a écrit dans le message :
4266bda8$0$14370$

Arg!!! mais bien sur!!
J'ai vraiment besoin de vacances!


faire systématiquement :

struct conf *gblconf = NULL ;

pas d'UB possible, et le gros NULL titille les yeux du programmeur...

Avatar
DINH Viêt Hoà

struct conf *gblconf;
gblconf = malloc(sizeof(struct conf));
gblconf->single_user = 0;

Il est étonnant que ça fonctionne, d'ailleurs.


sans oublier qu'il serait intéressant de vérifier que l'allocation
mémoire a bien réussi.

--
DINH V. Hoa,

"sunZ ! capitaine de soirées"

Avatar
Emmanuel Delahaye
Stephane Legras-Decussy wrote on 21/04/05 :
faire systématiquement :

struct conf *gblconf = NULL ;


Oui ou donner tout de suite la bonne valeur...

struct conf *gblconf = malloc(sizeof *gblconf);

ou

struct conf *gblconf = &Gblconf;

etc.

pas d'UB possible,


Si, mais au moins, il y a un moyen de le tester.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"

Avatar
hibiki
Bonsoir,

Lorsque je compile ce code sur 2 machines différentes (a et b)
(GNU/Linux Debian pour info) et sans aucune erreur, sur l'une (a) le
binaire résultant s'éxécute parfaitement, et sur l'autre (b) j'ai un
segfault (sur l'affectation gblconf->single_user = 0; ).
Si je prend le binaire de la première machine (a) que je le copie sur
(b), il s'exécute bien également.
Je ne peux pas croire qu'il s'agisse que d'un problème de compilateur.
J'ai certainement fais une bourde plus grosse que moi, mais elle ne me
saute pas aux yeux... Quelqu'un pourrait me l'indiquer?


#include <stdlib.h>

struct conf
{
unsigned int single_user;
};

int
main (void)
{
struct conf *gblconf;

gblconf->single_user = 0;

exit (EXIT_SUCCESS);
}



Merci de votre aide


Il ne faudrait peut-être pas oublier de réserver un espace mémoire pour
la stucture...
Etant donné qu'il ne s'agit que d'un uint (32bits), le débordement n'est
pas forcément détecté, vu que le pointeur gblconf n'est pas forcément
initialisé à NULL.
Une des tes distrib doit l'initialiser à NULL, ce qui explique l'erreur.

2 solutions :

struct conf gblconf;
gblconf.single_user = 0;

ou

struct conf* gblconf;
gblconf = malloc(sizeof(struct conf));

gblconf->single_user = 0;

free(gblconf);


--
Salutations,

Joachim Naulet

06 14 90 06 21
http://jnaulet.no-ip.com