erreurs classiques
Il y a deux fautes que beaucoup d'étudiants font, surtout s'ils savent
programmer en Java:
- Mauvaise utilisation des structures au niveau des fonctions:
Il ne faut jamais passer directement des structures comme type d'entrée ou de sortie d'une fonction; il faut toujours passer par un pointeur sur une structure.
- Mauvaise utilisation des pointeurs dans les fonctions:
Il ne faut jamais retourner (depuis une fonction) un pointeur sur la pile d'une fonction; car cette zone mémoire va disparaître quand la fonction va retourner. (Les variables locales "vivent" sur la pile.)
Petit rappel, soit le code C suivant:
int n=5;
int foo() {
int b;
}
int main() {
int a;
foo();
}
Voici ce qui se passe au niveau de la pile:
- la pile de main est crée. Elle contient entre autre la variable a.
- le code de main est executé.
- main va appeler foo.
- la pile de foo est crée. Elle contient entre autre la variable b.
- le code de foo est executé.
- la pile de foo est détruite. La variable b n'existe plus.
- on revient dans main.
- la pile de main est détruite. La variable a n'existe plus.
Voici maintenant une série de différents code C qui essayent de faire la même chose, créer un "objet" rectangle, mais qui contiennent tous des grosses erreurs:
typedef struct _rectangle {
int width;
int height;
} rectangle;
Code 1 - ne repect pas la première règle
rectangle create(int w, int h) {
rectangle r;
r.width = w;
r.height = h;
return r;
}
int main() {
rectangle r1 = create(5, 6);
rectangle r2 = create(12, 3);
}
Ce code (qui marche) provoque des copies de la structure au niveau du return.
Code 2 - ne respect pas la deuxième règle
rectangle* create(int w, int h) {
rectangle r;
r.width = w;
r.height = h;
return &r;
}
int main() {
rectangle* r1 = create(5, 6);
rectangle* r2 = create(12, 3);
}
Ce code est faux !
Voici donc deux solutions qui sont bonnes:
Solution 1 - create va allouer l'"objet" (sur le heap)
rectangle* create(int w, int h) {
rectangle* r = (rectangle*)malloc(sizeof(rectangle));
r->width = w;
r->height = h;
return r;
}
int main() {
rectangle* r1 = create(5, 6);
rectangle* r2 = create(12, 3);
// ne pas oublier ensuite de faire free(r1) et free(r2) !
}
Solution 2 - on va allouer rectangle sur la pile, mais de main
void create(rectangle* r, int w, int h) {
r->width = w;
r->height = h;
}
int main() {
rectangle r1, r2;
create(&r1, 5, 6);
create(&r2, 12, 3);
}