TD4 : Pointeurs, Copies profondes
3
struct s1 { int i; };
struct s2 { struct s1 s; };
struct s3 { struct s1 *p; };
14.
NB : b->s
= (*b).s
struct s1 *a = malloc(sizeof(struct s1));
(*a).i = 42; // ou : a->i=42;
struct s2 *b = malloc(sizeof(struct s2));
b->s=*a;
digraph structs {
node [shape=record];
struct1 [shape=record,label="<f0>a"];
struct2 [shape=record,label="<f0> i=42"];
struct3 [shape=record,label="<f0>b"];
struct4 [shape=record,label="<f0> i=42"];
struct1:f0 -> struct2:f0;
struct3:f0 -> struct4:f0;
}
15
struct s1 s1; // oui, on peut donner le meme nom a une
struct s2 s2; // variable et a un type struct...
struct s3 s3, ss3;
s1.i = 42; s2.s1 = s1;
s3.p = &s1;
ss3.p = malloc (sizeof (struct s1)); ss3.p->i = 54;
- La pile : on y met les variables locales, etc..
- Le tas : où se retrouvent les données “mallocées” : bien moins ordonné
16
*f(void)
VS *f()
:
*f(void)
: ne prend jamais aucun argument*f()
: ne prend pas, a priori, d’argument, mais ne renvoie pas d’erreur si on lui en donne.
struct s1 *f(void) {
struct s1 s;
s.i = 42;
return &s;
}
gros pb : &s
: tout est effacé à la sortie de la fonction, quand pile dépilée vers l’adresse de retour. (structure libérée après l’appel)
Pour pallier ce pb : malloc
: survit après l’appel de la fonction.
17
struct s3 *f(void) {
struct s1 s; s.i = 9;
struct s3 *p3 = malloc (sizeof (struct s3));
p3->p = &s;
return p3;
}
même problème : le pointeur p
ne pointe vers plus rien, après l’appel de la fonction
Correction :
struct s3 *f(void) {
a = malloc(sizeof struct s1);
a->i=9;
struct s3 *p3 = malloc (sizeof (struct s3));
p3->p = a;
return p3;
}
19
La première : taille infinie en mémoire.
20
En Java (comme en CamL, d’ailleurs), déclarer un type, c’est déclarer un pointeur vers ce type. Donc ça revient à la deuxième option de la question précédente (en C).
21
En C : comme l’inclusion de structures est autorisées :
- économie de mémoire
- permet des copies en dur : modification de l’une ne modifie pas l’autre
Ex :
- Graphport pour les premiers Macs : pour imprimer (avec des pointeurs).
22
Ca marche sans, et de toute façon : on n’utilise pas de pointeurs dans ces langages.
23
void *memchr(const void *s, int c, size_t n);
void *
: pointeur générique, vers n’importe quel type.
void *memchr(const void *s, int c, size_t n){
size_t i;
const unsigned char *sp=s;
unsigned char cc;
for(i=0; i<n; i++){
cc = *sp++;
if (cc == c)
return sp-1
}
return NULL;
}
Leave a comment