-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathseries-c-26.tex
203 lines (175 loc) · 5.2 KB
/
series-c-26.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
\documentclass[french,a4paper,addpoints,11pt]{exam}
\usepackage{hexercises}
\usepackage{mathtools, nccmath}
\usepackage{tabularx}
\title{L'allocation dynamique}
\seriesno{\texttt{0x26}}
\department{TIN}
\classroom{INFO2-TIN}
\setlength\answerlinelength{10 cm}
\setlength\answerskip{3ex}
\setlength\answerclearance{1.1ex}
\CorrectChoiceEmphasis{}
\renewcommand{\thepartno}{\alph{partno}}
\renewcommand{\partlabel}{\thepartno.}
\renewcommand{\arraystretch}{1.75} % expand the cells vertically
\begin{document}
\maketitle
\thispagestyle{headandfoot}
\ifprintanswers
\else
\begin{multicols}{2}
\fi
\begin{questions}
\question
On souhaite lire un fichier dont la taille n'est pas connue avant l'exécution du programme. Un espace mémoire doit alors être réservé sur le \emph{heap}. Écrire la fonction \CD{load} permettant de charger l'ensemble du fichier en mémoire dans la variable \CD{data}.
\begin{lstlisting}
int main(int argc, char*argv[]) {
assert(argc > 1);
FILE *fp = fopen(argv[1]);
assert(fp != NULL);
char *data;
load(&data, fp);
close(fp);
}
\end{lstlisting}
\begin{solution}
\begin{lstlisting}
void load(char **data, FILE*fp) {
assert(fp != NULL);
fseek(fp, 0, SEEK_END);
size_t size = ftell(fp);
fseek(fp, 0, SEEK_SET);
*data = malloc(size);
assert(*data != NULL);
fread(*data, 1, size, fp);
}
\end{lstlisting}
\end{solution}
\question
Une structure avec un membre flexible est défini comme suit :
\begin{lstlisting}
typedef struct point {
int x; int y;
} Point;
typedef struct record {
int id;
Point points[];
} Record;
\end{lstlisting}
\begin{parts}
\part Quelle est la taille de la structure record en bytes?
\begin{solution}
Le membre flexible n'est pas inclus dans la structure, cette dernière est donc la taille de l'entier 32-bit, soit 4 bytes.
\end{solution}
\part Déclarez la variable \CD{r} puis allouer l'espace mémoire nécessaire pour y stocker 10 points.
\begin{solution}
\begin{lstlisting}
Record *r = malloc(sizeof(Record) + sizeof(Point) * 10);
assert(r != NULL);
\end{lstlisting}
\end{solution}
\part Redimensionnez la variable \CD{r} pour y stocker jusqu'à 100 points.
\begin{solution}
\begin{lstlisting}
void *tmp = realloc(sizeof(Record) + sizeof(Point) * 100, 1);
assert(tmp != NULL);
r = tmp;
\end{lstlisting}
\end{solution}
\part À la fin de l'exercice, il est nécessaire de libérer l'espace mémoire utilisé. Comment libérez-vous l'espace alloué ?
\begin{solution}
\begin{lstlisting}
free(r);
\end{lstlisting}
\end{solution}
\end{parts}
\question Une fonction s'occupe de redimensionner un set de données pour pouvoir y stocker \CD{n} valeurs. Écrire la fonction \CD{resize}.
\begin{parts}
\part Dans le premier cas le set de donnée est défini comme suit:
\begin{lstlisting}
typedef struct measurements {
size_t elements; // Nombre d'éléments dans le set
size_t capacity; // Capacité en éléments de l'espace alloué
int *data;
} Measurements;
\end{lstlisting}
\begin{solution}
\begin{lstlisting}
int resize(Measurements *meas, size_t n) {
if (n < meas->elements)
return 1;
if (meas->data == NULL) {
meas->data = malloc(sizeof(Measurements.data[0]));
if (meas->data == NULL) return 2;
meas->capacity = n;
return 0;
}
meas->capacity = n;
void *tmp = realloc(meas->data, sizeof(Measurements.data[0]) * meas->capacity;
if (tmp == NULL) return 3;
meas->data = tmp;
return 0;
}
\end{lstlisting}
\end{solution}
\part Dans le second cas le set de donnée est défini à l'aide d'un membre flexible :
\begin{lstlisting}
typedef struct measurements {
size_t elements; // Nombre d'éléments dans le set
size_t capacity; // Capacité en éléments de l'espace alloué
int data[];
} Measurements;
\end{lstlisting}
\begin{solution}
\begin{lstlisting}
int resize(Measurements **meas, size_t n) {
if ((*meas) == NULL) {
(*meas) = malloc(sizeof(Measurements) + n * sizeof(Measurements.data[0]));
(*meas)->capacity = n;
(*meas)->elements = 0;
if ((*meas) == NULL) return 2;
return 0;
}
if (n < (*meas)->elements)
return 1;
(*meas)->capacity = n;
void *tmp = realloc((*meas),
sizeof(Measurements) + n * sizeof(Measurements.data[0]));
if (tmp == NULL) return 3;
(*meas) = tmp;
return 0;
}
\end{lstlisting}
\end{solution}
\end{parts}
\question Dans un jeu de Sudoku, on souhaite allouer l'espace nécessaire pour y stocker une grille dont la taille (nombre de colonnes) est déterminée à l'exécution du programme.
La grille est stockée dans un pointeur sur un tableau à deux dimensions, dont chaque dimension est la taille de la variable \CD{columns}.
\begin{parts}
\part Écrire la structure de donnée et allouer cette grille en initialisant toutes les valeurs à zéro.
\begin{solution}
\begin{lstlisting}
const int columns = 10;
assert(columns < UINT8_MAX);
uint8_t (*grid)[][columns] = calloc(sizeof(uint8_t), columns * columns);
assert(grid != NULL);
\end{lstlisting}
\end{solution}
\part Affichez la grille sur la sortie standard.
\begin{solution}
\begin{lstlisting}
for(int i = 0; i < columns; i++) {
for(int j = 0; j < columns; j++) {
printf("%d ", (*grid)[i][j]);
}
printf("\n");
}
\end{lstlisting}
\end{solution}
\end{parts}
\end{questions}
\ifprintanswers
\else
\end{multicols}
\fi
\end{document}