Программирование для Linux. Профессиональный подход.

А.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);

   if (sscanf(command, "%u %i", &array_index,

    &size_or_position) == 2 &&

    array_index < array_size).

    allocate(&(array[array_index]), size_or_position);

   else.

    error = 1;

   break;

  case 'd':

   fgets(command, sizeof(command), stdin);

   if (sscanf(command, "%u", &array_index) == 1 &&

    array_index < array_size).

    deallocate(&(array[array_index]));

   else.

    error = 1;

   break;

  case 'r':

   fgets(command, sizeof(command), stdin);

   if (sscanf(command, "%u %i", &array_index,

    &size_or_position) == 2 &&

    array_index < array_size).

    read_from_memory(array[array_index], size_or_position);

   else.

    error = 1;

   break;

  case 'w':

   fgets(command, sizeof(command), stdin);

   if (sscanf(command, "%u %i", &array_index,

    &size_or_position) == 2 &&

    array_index < array_size).

    write_to_memory(array[array_index], size_or_position);

   else.

    error = 1;

   break;

  case 'q':

   free((void*)array);

   return 0;

  default:

   error = 1;

  }

 }

 free((void*)array);

 return 1;

}