Programmation C
Gestion de la mémoire - Correction des exercices
Cours Exercices Correction des exercices

Exercice 1 Exercice 2 Exercice 3 Exercice 4
Exercice 5 Exercice 6 Exercice 7 Exercice 8

Exercice 1

#include <stdio.h>
#include <stdlib.h>

void main(void) {
  int v = 100000000;
  printf("%d\n", v);
  printf("%zu\n", sizeof(v));
  printf("%p\n", &v);
  int* pv1 = &v;
  printf("%zu\n", sizeof(pv1));
  printf("%d\n", *pv1);
  ++*pv1;      // (*pv1)++ marche aussi
  printf("%d\n", *pv1);
  unsigned char* pv2 = (unsigned char*) &v;
  printf("%2X %3d\n", *pv2, *pv2);
  printf("%2X %3d\n", *(pv2 + 1), *(pv2 + 1));
  printf("%2X %3d\n", *(pv2 + 2), *(pv2 + 2));
  printf("%2X %3d\n", *(pv2 + 3), *(pv2 + 3));
  *(pv2 + 1) = 100;
  printf("%d\n", v);
}

06-Exercice1.c - 06-Exercice1.exe
100000000
4
0000007559CFF9B0
8
100000000
100000001
 1   1
E1 225
F5 245
 5   5
99968001
  • Remarques sur le programme :
    • Utilisation du + sur pointeur pour faire des décalages d'adresse (attention, la valeur ajoutée désigne le nombre d'enregistrements de décalage pas le nombre d'octets de décalage)
    • Attention à l'éventuelle utilisation nécessaire de parenthèses sur les accès aux valeurs pointées par les pointeurs à cause des priorités associées aux opérateurs (++ puis * puis + dans l'ordre du plus prioritaire ou moins prioritaire) : *(pv2 + 1) pour calculer l'adresse égale à celle contenue dans pv2 décalée de un enregistrement car *pv2 + 1 réaliserait (*pv2) + 1 c'est à dire le calcul de 1 + contenu pointé par pv2
  • Réponses aux questions
    • 100000001 = 5*2563+245*2562+225*256+1 c'est à dire que les valeurs des octets donnent les chiffres de v en base 256 (chiffres codés sur un octet).
      A noter, les chiffres sont donnés en ordre unité, "dizaine", "centaine"...
    • Si on change le 225 en 100, on change la valeur de v en lui retirant (225-100)*256.

Exercice 2

#include <stdio.h>
#include <stdlib.h>

void main(void) {
  int n = 1000000;
  size_t taille = n * sizeof(double);
  printf("%zu\n", taille);
  double* td = (double*) malloc(taille);
  printf("%zu %p %p\n", sizeof(td), &td, td);
  if (td != NULL) {
    for (int i = 0; i < n; i++) {
      td[i] = (rand() % 101) / 100.0;
    }
    double somme = 0.0;
    for (int i = 0; i < n; i++) {
      somme += td[i];
    }
    double moyenne = somme / n;
    printf("%lf\n", moyenne);
  }
  if (td != NULL) {
    free(td);
    td = NULL;
  }
}

06-Exercice2.c - 06-Exercice2.exe
8000000
8 0000007C74AFFD90 000001A081502040
0.499682
  • RAS

Exercice 3

#include <stdio.h>
#include <stdlib.h>

void main(void) {
  size_t taille = 100000000;
  char* tc = (char *) calloc(taille,sizeof(char));
  if (tc != NULL) {
    int cpt = 0;
    for (int i = 0; i < taille; i++) {
      if (tc[i] != 0x00) {
        cpt++;
      }
    }
    printf("%d valeur(s) differentes de 0x00\n", cpt);
  }
  if (tc != NULL) {
    free(tc);
    tc = NULL;
  }
}

06-Exercice3.c - 06-Exercice3.exe
0 valeur(s) differentes de 0x00
  • RAS

Exercice 4

#include <stdio.h>
#include <stdlib.h>

void main(void) {
  int n1 = 100;
  size_t taille1 = n1 * sizeof(int);
  int* ti = (int*) malloc(taille1);
  printf("%p\n", ti);
  if (ti != NULL) {
    for (int i = 0; i < n1; i++) {
      ti[i] = 1;
    }
    int n2 = 1000;
    size_t taille2 = n2 * sizeof(int);
    int* tmp = realloc(ti, taille2);
    if (tmp != NULL) {
      ti = tmp;
      printf("%p\n", ti);
      int i = 0;
      while ((i < n1) && (ti[i]) == 1) {
        i++;
      }
      if ((i < n1) || (ti[n1 - 1] != 1)) {
        printf("Probleme de copie!\n");
      }
    }
  }
  if (ti != NULL) {
    free(ti);
    ti = NULL;
  }
}

06-Exercice4.c - 06-Exercice4.exe
0000021F70E30070
0000021F70E31FE0
  • RAS

Exercice 5

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

bool* creerTableauBooleensEquiprobables(int n) {
  bool* t = (bool*) calloc(n, sizeof(bool));
  if (t != NULL) {
    for (int i = 0; i < n; i++) {
      if (rand() % 2 == 0) {
        t[i] = true;
      }
    }
  }
  return t;
}

int calculerNombreCouplesDeVraiConsecutifs(bool* t, int n) {
  if (t == NULL) {
    return 0;
  }
  int cpt = 0;
  for (int i = 0; i < n - 1; i++) {
    if (t[i] && t[i + 1]) {
      cpt++;
    }
  }
  return cpt;
}

void main(void) {
  srand(10);
  int n = 50000;
  bool* tb = creerTableauBooleensEquiprobables(n);
  if (tb != NULL) {
    printf("%d couples de vrai consecutifs\n", calculerNombreCouplesDeVraiConsecutifs(tb, n));
  }
  if (tb != NULL) {
    free(tb);
    tb = NULL;
  }
}

06-Exercice5.c - 06-Exercice5.exe
12496 couples de vrai consecutifs
  • RAS

Exercice 6

#include <stdio.h>
#include <stdlib.h>

int** creerMatrice(size_t nbL, size_t nbC) {
  int** mat;
  mat = calloc(nbL, sizeof(int*));
  if (mat != NULL) {
    int *m =(int *) calloc(nbL * nbC, sizeof(int));
    mat[0] = m;
    if (m != NULL) {
      for (int l = 1; l < nbL; l++) {
        mat[l] = &m[l * nbC];
      }
    }
    else {
      free(mat);
      mat = NULL;
    }
  }
  return mat;
}

void detruireMatrice(int** mat) {
  if (mat != NULL) {
    if (mat[0] != NULL) {
      free(mat[0]);
      mat[0] = NULL;
    }
    free(mat);
    mat = NULL;
  }
}

long long calculerNombreOccurrences(int** mat, size_t nbL, size_t nbC, int v) {
  long long cpt = 0;
  if (mat != NULL) {
    for (int l = 0; l < nbL; l++) {
      for (int c = 0; c < nbC; c++) {
        if (mat[l][c] == v) {
          cpt++;
        }
      }
    }
  }
  return cpt;
}

void initialiser(int** mat, size_t nbL, size_t nbC, int v) {
  if (mat != NULL) {
    for (int l = 0; l < nbL; l++) {
      for (int c = 0; c < nbC; c++) {
        mat[l][c] = v;
      }
    }
  }
}

int main(void) {
  int** m1 = creerMatrice(1, 1);
  printf("m1 : %p\n", m1);
  initialiser(m1, 1, 1, 10);
  printf("Nombre de valeurs egales a 10 : %lld\n", calculerNombreOccurrences(m1, 1, 1, 10));
  printf("\n");
  detruireMatrice(m1);
  size_t nbC = 5000000;
  printf("Nombre de colonnes : %zu\n", nbC);
  m1 = NULL;
  for (int i = 1; i <= 25; i++) {
    size_t nbL = i * (size_t) 200;
    int** m = creerMatrice(nbL, nbC);
    printf("Matrice de %4zu lignes : %20p\n", nbL, m);
    initialiser(m, nbL, nbC, i);
    printf("Nombre de valeurs      : %20lld\n", calculerNombreOccurrences(m, nbL, nbC, i));
    detruireMatrice(m);
    m = NULL;
  }
  return 0;
}

06-Exercice6.c - 06-Exercice6.exe
m1 : 000001755F41BC60
Nombre de valeurs egales a 10 : 1

Nombre de colonnes : 5000000
Matrice de  200 lignes :     000001755F420EE0
Nombre de valeurs :                1000000000
Matrice de  400 lignes :     000001755F422FE0
Nombre de valeurs :                2000000000
Matrice de  600 lignes :     000001755F422FE0
Nombre de valeurs :                3000000000
Matrice de  800 lignes :     000001755F422FE0
Nombre de valeurs :                4000000000
Matrice de 1000 lignes :     000001755F422FE0
Nombre de valeurs :                5000000000
Matrice de 1200 lignes :     000001755F422FE0
Nombre de valeurs :                6000000000
Matrice de 1400 lignes :     000001755F422FE0
Nombre de valeurs :                7000000000
Matrice de 1600 lignes :     000001755F422FE0
Nombre de valeurs :                8000000000
Matrice de 1800 lignes :     000001755F422FE0
Nombre de valeurs :                9000000000
Matrice de 2000 lignes :     000001755F422FE0
Nombre de valeurs :               10000000000
Matrice de 2200 lignes :     000001755F422FE0
Nombre de valeurs :               11000000000
Matrice de 2400 lignes :     000001755F422FE0
Nombre de valeurs :               12000000000
Matrice de 2600 lignes :     000001755F422FE0
Nombre de valeurs :               13000000000
Matrice de 2800 lignes :     000001755F422FE0
Nombre de valeurs :               14000000000
Matrice de 3000 lignes :     000001755F422FE0
Nombre de valeurs :               15000000000
Matrice de 3200 lignes :     000001755F422FE0
Nombre de valeurs :               16000000000
Matrice de 3400 lignes :     000001755F422FE0
Nombre de valeurs :               17000000000
Matrice de 3600 lignes :     000001755F422FE0
Nombre de valeurs :               18000000000
Matrice de 3800 lignes :     000001755F422FE0
Nombre de valeurs :               19000000000
Matrice de 4000 lignes :     000001755F422FE0
Nombre de valeurs :               20000000000
Matrice de 4200 lignes :     000001755F422FE0
Nombre de valeurs :               21000000000
Matrice de 4400 lignes :     0000000000000000
Nombre de valeurs :                         0
Matrice de 4600 lignes :     0000000000000000
Nombre de valeurs :                         0
Matrice de 4800 lignes :     0000000000000000
Nombre de valeurs :                         0
Matrice de 5000 lignes :     0000000000000000
Nombre de valeurs :                         0
  • RAS

Exercice 7

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* creerCopieChaineDeCaracteres(char* s) {
  char* dst = (char*) calloc(strlen(s) + 1, sizeof(char));
  if (dst != NULL) {
    strcpy(dst, s);
  }
  return dst;
}

void main(void) {
  char* s = "abcdefgh";
  char* ns = creerCopieChaineDeCaracteres(s);
  if (ns != NULL) {
    printf("Chaine a copier : %s\n", s);
    printf("Chaine copiee   : %s\n", ns);
  }
  if (ns != NULL) {
    free(ns);
    ns = NULL;
  }
}

06-Exercice7.c - 06-Exercice7.exe
Chaine a copier : abcdefgh
Chaine copiee   : abcdefgh
  • RAS

Exercice 8

#include <stdio.h>
#include <stdlib.h>

long long** creerTriangle(int n) {
  long long** tr;
  tr = calloc(n, sizeof(long long*));
  if (tr != NULL) {
    long long* m = (long long*) calloc((n * (n + 1)) / 2, sizeof(long long));
    tr[0] = m;
    m++;
    if (m != NULL) {
      for (int l = 1; l < n; l++) {
        tr[l] = m;
        m += (l + 1);
      }
    }
    else {
      free(tr);
      tr = NULL;
    }
  }
  return tr;
}

void detruireTriangle(long long** tr) {
  if (tr != NULL) {
    if (tr[0] != NULL) {
      free(tr[0]);
      tr[0] = NULL;
    }
    free(tr);
    tr = NULL;
  }
}

long long** creerTrianglePascal(int n) {
  long long** tr = creerTriangle(n);
  if (tr != NULL) {
    tr[0][0] = 1;
    for (int l = 1; l < n; l++) {
      tr[l][0] = 1;
      tr[l][l] = 1;
    }
    for (int l = 2; l < n; l++) {
      for (int c = 1; c < l; c++) {
        tr[l][c] = tr[l - 1][c] + tr[l - 1][c - 1];
      }
    }
  }
  return tr;
}

void afficherTriangle(long long** tr, int n) {
  for (int l = 0; l < n; l++) {
    for (int c = 0; c <= l; c++) {
      printf("%5lld", tr[l][c]);
    }
    printf("\n");
  }
}

int main(void) {
  int n = 15;
  printf("Taille du triangle : %d\n", n);
  long long** tr = creerTrianglePascal(n);
  if (tr != NULL) {
    afficherTriangle(tr, n);
    tr = NULL;
  }
  detruireTriangle(tr);
  tr = NULL;
  return 0;
}

06-Exercice8.c - 06-Exercice8.exe
Taille du triangle : 15
   1
   1    1
   1    2    1
   1    3    3    1
   1    4    6    4    1
   1    5   10   10    5    1
   1    6   15   20   15    6    1
   1    7   21   35   35   21    7    1
   1    8   28   56   70   56   28    8    1
   1    9   36   84  126  126   84   36    9    1
   1   10   45  120  210  252  210  120   45   10    1
   1   11   55  165  330  462  462  330  165   55   11    1
   1   12   66  220  495  792  924  792  495  220   66   12    1
   1   13   78  286  715 1287 1716 1716 1287  715  286   78   13    1
   1   14   91  364 1001 2002 3003 3432 3003 2002 1001  364   91   14    1
  • RAS