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

realloc

5 réponses
Avatar
matt
Bonjour,

Si je désire utiliser la fonction realloc, faut-il que j'ai deux
pointeurs, du style;

char *ptr1 = NULL, *ptr2 = NULL;

ptr1 = malloc(10 * sizeof(char));
if(ptr1 == NULL)
exit(EXIT_FAILURE);

../..

ptr2 = realloct(ptr1, 20 * sizeof(char));


dans ce cas, trois possibilités, il me semble :

1 - tout est ok, ptr2 == ptr1 et un free(ptr1); fait l'affaire.

2 - ptr2 != ptr1 et ptr2 != NULL, ok, mais faut-il liberer ptr1 juste
apres le realloc et un free(ptr2); en fin d'utilisation.

3 - dommage, ptr2 == NULL; donc juste un free(ptr1);

suis je dans le juste ?

Merci pour vos réponses,

Matt...

5 réponses

Avatar
espie
In article <460fab64$0$5111$,
matt wrote:
Bonjour,

Si je désire utiliser la fonction realloc, faut-il que j'ai deux
pointeurs, du style;

char *ptr1 = NULL, *ptr2 = NULL;

ptr1 = malloc(10 * sizeof(char));
if(ptr1 == NULL)
exit(EXIT_FAILURE);

../..

ptr2 = realloct(ptr1, 20 * sizeof(char));


dans ce cas, trois possibilités, il me semble :

1 - tout est ok, ptr2 == ptr1 et un free(ptr1); fait l'affaire.

2 - ptr2 != ptr1 et ptr2 != NULL, ok, mais faut-il liberer ptr1 juste
apres le realloc et un free(ptr2); en fin d'utilisation.


Non, le realloc a deplace les donnees et libere la vieille zone.

3 - dommage, ptr2 == NULL; donc juste un free(ptr1);


OUI, c'est le gag un peu vicieux: si realloc() echoue, la vieille zone
memoire reste disponible.

En general, on utilise souvent un idiome de type:


{
char *np = realloc(p, newsize);
if (np)
p = np; // oui, je sais, mauvais jeu de mot
else {
// echec
free(p);
exit(EXIT_FAILURE); // ou assimile
}
}

Avatar
matt
In article <460fab64$0$5111$,
matt wrote:
Bonjour,

Si je désire utiliser la fonction realloc, faut-il que j'ai deux
pointeurs, du style;

char *ptr1 = NULL, *ptr2 = NULL;

ptr1 = malloc(10 * sizeof(char));
if(ptr1 == NULL)
exit(EXIT_FAILURE);

../..

ptr2 = realloct(ptr1, 20 * sizeof(char));


dans ce cas, trois possibilités, il me semble :

1 - tout est ok, ptr2 == ptr1 et un free(ptr1); fait l'affaire.

2 - ptr2 != ptr1 et ptr2 != NULL, ok, mais faut-il liberer ptr1 juste
apres le realloc et un free(ptr2); en fin d'utilisation.


Non, le realloc a deplace les donnees et libere la vieille zone.

3 - dommage, ptr2 == NULL; donc juste un free(ptr1);


OUI, c'est le gag un peu vicieux: si realloc() echoue, la vieille zone
memoire reste disponible.

En general, on utilise souvent un idiome de type:


{
char *np = realloc(p, newsize);
if (np)
p = np; // oui, je sais, mauvais jeu de mot
else {
// echec
free(p);
exit(EXIT_FAILURE); // ou assimile
}
}



Merci bien,

Bonne journée,

Matt...


Avatar
Laurent Deniau
Marc Espie wrote:
In article <460fab64$0$5111$,
matt wrote:
Bonjour,

Si je désire utiliser la fonction realloc, faut-il que j'ai deux
pointeurs, du style;

char *ptr1 = NULL, *ptr2 = NULL;

ptr1 = malloc(10 * sizeof(char));
if(ptr1 == NULL)
exit(EXIT_FAILURE);

../..

ptr2 = realloct(ptr1, 20 * sizeof(char));


dans ce cas, trois possibilités, il me semble :

1 - tout est ok, ptr2 == ptr1 et un free(ptr1); fait l'affaire.

2 - ptr2 != ptr1 et ptr2 != NULL, ok, mais faut-il liberer ptr1 juste
apres le realloc et un free(ptr2); en fin d'utilisation.


Non, le realloc a deplace les donnees et libere la vieille zone.

3 - dommage, ptr2 == NULL; donc juste un free(ptr1);


OUI, c'est le gag un peu vicieux: si realloc() echoue, la vieille zone
memoire reste disponible.

En general, on utilise souvent un idiome de type:


{
char *np = realloc(p, newsize);
if (np)
p = np; // oui, je sais, mauvais jeu de mot
else {
// echec
free(p);
exit(EXIT_FAILURE); // ou assimile
}
}


Et si newsize == 0, on a un joli segfault ;-)

a+, ld.


Avatar
espie
In article <euqdmu$oji$,
Laurent Deniau wrote:
Et si newsize == 0, on a un joli segfault ;-)


Bien sur, mais on s'adresse pas a des debiles non plus. C'est un *idiome*
pas un code de fonction complet. Comme de toutes facons, realloc
s'utilise surtout pour faire grossir des trucs, c'est rare d'avoir newsize
qui vaut zero.

Par contre, c'est bien plus frequent d'avoir un risque d'integer overflow,
donc autant en parler.

Situation: on a un ensemble d'objets, mettons des struct foo, stockees
dans un tableau de N elements.

La taille du tableau va donc etre: N * sizeof(struct foo).

Attention: si N * sizeof(struct foo) est plus grand qu'un size_t, on va
allouer moins que ce qu'on croit, ne pas avoir

Ca peut se detecter en demandant a size_t ce qu'il en pense.
#include <stdint.h>
if (SIZE_MAX/N > sizeof(struct foo))
// houston, on a un probleme

avant d'utiliser une fonction d'allocation/realloaction.

(ne pas trop compter sur calloc, vu qu'un certain nombre d'implementations
sont bugguees jusqu'a l'os...)

Avatar
Laurent Deniau
Marc Espie wrote:
In article <euqdmu$oji$,
Laurent Deniau wrote:
Et si newsize == 0, on a un joli segfault ;-)


Bien sur, mais on s'adresse pas a des debiles non plus.


C'est une erreur tres frequente, meme chez les experts...

http://groups.google.fr/group/comp.lang.c/tree/browse_frm/thread/91adfd8ff99452cc/38031b24a5d1d138

C'est un *idiome*
pas un code de fonction complet. Comme de toutes facons, realloc
s'utilise surtout pour faire grossir des trucs, c'est rare d'avoir newsize
qui vaut zero.


Et donc de facon *idiomatique*, il faut considerer le cas ou newsize
vaut zero pour malloc, calloc et realloc.

Par contre, c'est bien plus frequent d'avoir un risque d'integer overflow,
donc autant en parler.


Dans ta version *idiomatique*, il n'y pas de possibilite d'overflow (ni
dans celle du PO d'ailleurs).

a+, ld.