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

setjmp et memoire dynamique : question naïve

5 réponses
Avatar
Brocol
Bonjour,
J' ai découvert setjmp et longjmp il y a pas bien longtemps. Bien que parvenant
à peu près à m' en servir, j' ai du mal à comprendre leur utilité et j' ai un
peu peur d' avoir raté complètement le point...

L' exemple suivant constitue t il une utilisation possible de setjmp/longjmp ?
Est-ce que ça n' a strictement aucun intérêt d' utiliser setjmp/longjmp comme ça ?
Cela poserait il un réel problème si je me contentais de tester les retours de
malloc et que je sortais directement du programme ( exit(EXIT_FAILURE) ) en cas
d' échec de malloc ?

/*
* main.h
*/
[du code]
extern jmp_buf envbuf;
[du code]


/*
* main.c
*/
jmp_buf envbuf;

int
main (int argc, char *argv[])
{
[des declarations...];
int jmp_ret;

jmp_ret = setjmp(envbuf);

if ( !jmp_ret )
{
[du code, des appels à des fonctions definies dans d autres fichiers dont
certaines utilisent malloc/realloc]
}
else
{
printf(stderr, "Erreur allocation memoire, on sort.\n");
return 1;
}

return 0;
}

/*
* un fichier inclus par main.c
*/
#include "main.h"

int
uneFonction (des parametres)
{
[du code, des mallocs, des reallocs.]

Soudainement un malloc échoue.

if ( !(c = malloc(taille)) )
{
longjmp(envbuf, 1);
}

[code et fin de fonction]
}

Merci d' avance.

--
B. Coll

5 réponses

Avatar
Brocol
J' ai oublié la question qui me tracasse le plus :
Si j' ai bien compris, setjmp permet de "faire une copie" du contexte à un
instant donné. Est-ce que quand je fais un longjmp et que mon programme revient
dans son contexte "sauvegardé", la mémoire que j' aurais allouée entre le setjmp
et le longjmp ne sera plus allouée ? Je peux donc me dispenser de libérer la
mémoire que j' ai alloué pendant ce laps de temps et quitter lachement mon
programme la conscience tranquille ? (n ayant pas provoque de fuites)

--
B. Coll
Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Brocol wrote:

J' ai oublié la question qui me tracasse le plus :
Si j' ai bien compris, setjmp permet de "faire une copie" du contexte à
un instant donné. Est-ce que quand je fais un longjmp et que mon
programme revient dans son contexte "sauvegardé", la mémoire que j'
aurais allouée entre le setjmp et le longjmp ne sera plus allouée ? Je
peux donc me dispenser de libérer la mémoire que j' ai alloué pendant ce
laps de temps et quitter lachement mon programme la conscience
tranquille ? (n ayant pas provoque de fuites)


Le contexte dont il est question est le contexte d'exécution, notamment les
registres d'adresse, de mémoire, de pile, d'état etc. Rien à voir avec la
mémoire globale ou allouée etc.

J'ai utilisé stejmp()/longjump() (et quelques miettes d'assembleur) pour
réaliser un mini moniteur multitâche pour MS-DOS qui me sert en simulation.

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Emmanuel Delahaye wrote:

J'ai utilisé stejmp()/longjump()


Il y a longtemps!

J'ai utilisé setjmp()/longjmp()...

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Randolf Carter
Le contexte dont il est question est le contexte d'exécution,
notamment les

registres d'adresse, de mémoire, de pile, d'état etc. Rien à voir avec
la

mémoire globale ou allouée etc.


Est-il garanti que tout les registres soient systématiquement restaurés
?
J'ai connu des systèmes où ce code pouvait planter :

void foo(void)
{
void *p = malloc(123);
if (setjmp(envbuf))
free(p); /* Crash possible */
else
foo2(); /* Appelant longjmp */
}

tout simplement parce que p était stocké dans un registre non restauré.
La solution consistait alors à utiliser 'volatile' pour forcer
l'allocation de la variable sur la pile.
Soit :
volatile void *p = malloc(123);
ou même parfois
void * volatile p = malloc(123);

Que dit le standard ?

--
- Randolf

Avatar
Brocol
Emmanuel Delahaye wrote:

Le contexte dont il est question est le contexte d'exécution, notamment les
registres d'adresse, de mémoire, de pile, d'état etc. Rien à voir avec la
mémoire globale ou allouée etc.


D' accord merci.
--
B. Coll