Самьюэл Алекс
Шрифт:
Какое же из четырех средств выбрать? Поскольку чаще всего забывают согласовать число операций выделения и освобождения памяти, на начальных этапах разработки лучше применять утилиту
mtrace
. Она доступна во всех Linux-системах и хорошо себя зарекомендовала. Пройдя данную фазу тестирования, воспользуйтесь утилитой Electric Fence для нахождения неправильных обращений к памяти. Связка двух этих утилит позволяет найти практически все ошибки, связанные с использованием динамической памяти. А.2.7. Исходный текст программы, работающей с динамической памятью
В листинге А.2 показан исходный текст программы, на примере которой иллюстрируется выделение, освобождение и использование динамической памяти. Описание программы было дано в разделе А.2.1, "Программа для тестирования динамической памяти".
Листинг А.2. (malloc-use.c) Пример работы с динамической памятью
/
* Использование функций работы с динамической памятью. */
/* Программе передается один аргумент, определяющий
размер массива. Этот массив состоит из указателей
на (возможно) выделенные буферы памяти.
В процессе работы программы ей можно задавать
следующие команды:
выделение памяти -- а <индекс> <размер_буфера>
освобождение памяти -- d <индекс>
чтение памяти -- r <индекс> <смещение>
запись в память -- w <индекс> <смещение>
выход -- q
Ответственность за соблюдение правил доступа
к динамической памяти лежит на пользователе. */
#ifdef MTRACE
#include <mcheck.h>
#endif /* MTRACE */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
/* Выделение памяти указанного размера. */
void allocate(char** array, size_t size) {
*array = malloc(size);
}
/* Освобождение памяти. */
void deallocate(char** array) {
free((void*)*array);
}
/* Чтение указанной ячейки памяти. */
void read_from_memory(char* array, int position) {
volatile char character = array[position];
}
/* Запись в указанную ячейку памяти. */
void write_to_memory(char* array, int position) {
array[position] = 'a';
}
int main{int argc, char* argv[]) {
char** array;
unsigned array_size;
char command[32];
unsigned array_index;
char command_letter;
int size_or_position;
int error = 0;
#ifdef MTRACE
mtrace;
#endif /* MTRACE */
if (argc != 2) {
fprintf(stderr, "%s: array-size\n", argv[0]);
return 1;
}
array_size = strtoul(argv[1], 0, 0);
array = (char**)calloc(array_size, sizeof(char*));
assert(array != 0);
/* Выполнение вводимых пользователем команд. */
while (!error) {
printf("Please enter a command: ");
command_letter = getchar;
assert(command_letter != EOF);
switch (command_letter) {
case 'a':
fgets(command, sizeof(command), stdin);