teaching / slides > programmation 3 > erreurs classiques

erreurs classiques

Il y a deux fautes que beaucoup d'étudiants font, surtout s'ils savent programmer en Java:

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:

  1. la pile de main est crée. Elle contient entre autre la variable a.
  2. le code de main est executé.
  3. main va appeler foo.
  4. la pile de foo est crée. Elle contient entre autre la variable b.
  5. le code de foo est executé.
  6. la pile de foo est détruite. La variable b n'existe plus.
  7. on revient dans main.
  8. la pile de main est détruite. La variable a n'existe plus.
Note: la variable n n'est pas crée sur une pile, mais ailleurs (sur le heap).

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);
}