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

|
|

|
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
|
|
|
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
|
|
|
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
|
|
|
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 |
|
|
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
|
|
|
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
|
|
|
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 |
|
|