Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.12.2020

Просмотров: 4171

Скачиваний: 28

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Глава 20. Стандартные определения <stddef.h> 

281 

int main(void) 

  printf("shift of 'salary' = %d bytes\n", 
          offsetof(struct emp, salary));  // печатает 24 
 
  return 0; 

 


background image

  

 
 

Г Л А В А  

21 

 
 
 

Стандартные функции 

<stdlib.h> 

21.1. Динамическое распределение 

памяти 

Под динамической памятью понимают память, которая выделяет-
ся  программе  из  кучи.  Динамическое  распределение  памяти  за-
ключается в выделении программе по ее запросу памяти из кучи. 
Если программа завершила работу с распределенной ей памятью, 
то она должна освободить эту память, т. е. вернуть ее обратно в 
кучу. 
Для динамического распределения памяти в языке программиро-
вания  С  используются  функции 

malloc

calloc

  и 

realloc

.  Ниже 

приведены прототипы этих функций: 

  void* malloc(size_t size); 
  void* calloc(size_t n, size_t size); 
  void* realloc(void* ptr, size_t size); 

Работают эти функции следующим образом. 
Функция 

malloc

  выделяет  программе  память  размером  в 

size

 

байт. 
Функция 

calloc

 выделяет программе память размером в 

(n*size)

 

байт, при этом выделенная память обнуляется. 
Функция 

realloc

 перераспределяет память, на которую указывает 

параметр 

ptr

, до размера в 

size

 байтов. То есть программе вместо 

  

 


background image

Глава 21. Стандартные функции <stdlib.h> 

283 

старого распределяется новый блок памяти размером в 

size

 байт. 

При этом содержимое старого блока, но не более чем 

size

  байт, 

копируется  в  новый  блок.  Функция 

realloc

  используется  глав-

ным образом для увеличения размера выделенной памяти.  
Все эти функции в случае успеха возвращают указатель на выде-
ленную память, в случае неудачи — 

NULL

Символическая константа 

NULL

 также определена в заголовочном 

файле stdlib.h. Подробно эта константа была описана в 

разд. 20.2

Параметры 

size

  и 

n

  этих  функций  имеют  тип 

size_t

,  который 

обычно  является  переопределением  типа 

unsigned  int

.  Опреде-

ление этого типа было дано в 

разд. 20.1

. Тип 

size_t

 также опре-

делен и в заголовочном файле stdlib.h. 
Тип 

void*

  называется 

родовым  указателем

,  т. е.  указателем  на 

"сырую" или "пустую" память. Впоследствии этот указатель при-
водится к указателю на нужный тип. 
Для освобождения ранее выделенной программе памяти исполь-
зуется функция 

free

, которая имеет следующий прототип: 

  void free(void* ptr); 

Параметр 

ptr

  этой  функции  является  указателем  на  освобождае-

мую память. 
Сделаем  два  важных  замечания.  Во-первых,  динамическую  па-
мять  нужно  обязательно  освобождать  после  ее  использования. 
Иначе остаются неиспользованные блоки памяти, которые назы-
ваются  "мусором"  или 

утечками  памяти 

(memory  leaks).  Во-

вторых,  динамическое  выделение  памяти  используется  только  в 
том  случае,  если  программе  заранее  неизвестно,  какой  размер 
памяти  нужно  отвести  под  данные.  В  противном  случае  нужно 
использовать статическую память. 
В листинге 21.1 приведена программа, которая динамически рас-
пределяет память под целое число. 

Листинг 21.1. Динамическое распределение памяти 

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


background image

Часть III. Стандартная библиотека языка программирования C 

284 

int main() 

  char c; 
  int* p = NULL; 
  /* Нажмите 'y', чтобы ввести целое число */ 
  printf("Press 'y' to input integer: "); 
  scanf("%c", &c); 
  if (c == 'y') 
  { 
    /* выделяем память под целое число */ 
    p = (int*)malloc(sizeof(int)); 
    if (!p)  /* если ошибка, то выходим из программы */ 
    { 
      printf("Memory allocation failed.\n"); 
      return 0; 
    } 
    printf("Input integer: ");  /* Вводим целое число */ 
    scanf("%d", p); 
 
    printf("You input integer: %d\n", *p); 
    free(p); /* освобождаем память */ 
  } 
  else 
    printf("You don't want to input integer.\n"); 
 
  return 0; 

21.2. Динамические массивы 

Массив,  память  под  который  выделяется  во  время  исполнения 
программы, называется 

динамическим массивом

. Для того чтобы 

динамически  создать  одномерный  массив,  нужно,  во-первых, 
объявить  в  программе  указатель  на  тип,  соответствующий  типу 
элементов этого массива, а во-вторых, выделить память под мас-
сив, используя одну из функций 

malloc

 или 

calloc

В листинге 21.2 приведена программа, которая динамически соз-
дает одномерный целочисленный массив. 


background image

Глава 21. Стандартные функции <stdlib.h> 

285 

Листинг 21.2. Создание одномерного динамического массива 

#include <stdio.h> 
#include <stdlib.h> 
int main() 

  int *a, n;  /* указатель на массив и размерность массива */ 
  int i; 
 
  /* введите размерность массива */ 
  printf("Input a size of an array: "); 
  scanf("%d", &n); 
  /* выделяем память под массив */ 
  a = (int*)malloc(n * sizeof(int)); 
  if (!a)  /* если ошибка, то выходим из программы */ 
  { 
    printf("Memory allocation failed.\n"); 
    return 0; 
  } 
  /* вводим через пробел элементы массива */ 
  printf("Input elements of the array: "); 
  for (i = 0; i < n; ++i) 
    scanf("%d", &a[i]); 
  /* что-то делаем с массивом */ 
  printf("You input the array: "); 
  for (i = 0; i < n; ++i) 
    printf("%d ", a[i]); 
  printf("\n"); 
 
  free(a); /* освобождаем выделенную память */ 
 
  return 0; 

В  связи  с  этой  программой  заметим,  что  элементы  одномерного 
динамического массива можно ввести и следующим образом: 

  for (i = 0; i < n; ++i) 
    scanf("%d", a + i);  /* a – адрес массива */ 


Смотрите также файлы