Чтение онлайн

на главную - закладки

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

typedef struct bs_string { /* ... */ } bs_string; /* строка

Бьярне */

typedef int bs_bool; /* булев тип Бьярне */

/* in pete.h: */

typedef char* pete_string; /* строка Пита */

typedef char pete_bool; /* булев тип Пита */

Этот прием настолько широко используется, что использовать одно- и двухбуквенные префиксы обычно уже недостаточно.

27.4.

Свободная память

В языке С нет операторов

new
и
delete
, работающих с объектами. Для использования свободной памяти в нем используются функции, работающие с памятью. Наиболее важные функции определены в стандартном заголовочном файле общих утилит
<stdlib.h>
.

void* malloc(size_t sz); /* выделить sz байтов */

void free(void* p); /* освободить область памяти, на которую

ссылается указатель p */

void* calloc(size_t n, size_t sz); /* выделить n*sz байтов,

инициализировав их нулями */

void* realloc(void* p, size_t sz); /* вновь выделить sz байтов

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

указатель p*/

Тип

typedef size_t
— это тип без знака, также определенный в заголовочном файле
<stdlib.h>
.

Почему функция
malloc
возвращает указатель
void*
? Потому что она не имеет информации о том, объект какого типа вы хотите разместить в памяти. Инициализация — это ваша проблема. Рассмотрим пример.

struct Pair {

const char* p;

int val;

};

struct Pair p2 = {"apple",78};

struct Pair* pp = (struct Pair*) malloc(sizeof(Pair)); /* выделить
память */

pp–>p = "pear"; /* инициализировать */

pp–>val = 42;

Теперь мы не можем написать инструкцию

*pp = {"pear", 42}; /* ошибка: не C и не C++98 */

ни в программе на языке C, ни в программе на языке C++. Однако в языке С++ мы могли бы определить конструктор для структуры

Pair
и написать инструкцию
Pair* pp = new Pair("pear", 42)
;

В языке C (но не в языке C++; см. раздел 27.3.4) перед вызовом функции malloc можно не указывать приведение типа, но мы не рекомендуем это делать.

int* p = malloc(sizeof(int)*n); /* избегайте этого */

Игнорирование приведения довольно часто встречается в программах, потому что это экономит время и позволяет выявить редкую ошибку, когда

программист забывает включить в текст программы заголовочный файл
<stdlib.h>
перед использованием функции
malloc
. Однако при этом исчезает и визуальный маркер, свидетельствующий о том, что размер памяти подсчитан неправильно.

p = malloc(sizeof(char)*m); /* вероятно, ошибка — нет места для m целых */

Не используйте функции
malloc/free
в программах, написанных на языке C++; операторы
new/delete
не требуют приведения типа, выполняют инициализацию (вызывая конструкторы) и очищают память (вызывая деструкторы), сообщают об ошибках, связанных с распределением памяти (с помощью исключений), и просто работают быстрее. Не удаляйте объект, размещенный в памяти с помощью функции
malloc
, выполняя оператор
delete
, и не удаляйте объект, созданный с помощью оператора new, вызывая функцию
free
. Рассмотрим пример.

int* p = new int[200];

// ...

free(p); // ошибка

X* q = (X*)malloc(n*sizeof(X));

// ...

delete q; // error

Этот код может оказаться вполне работоспособным, но он не является переносимым. Более того, для объектов, имеющих конструкторы и деструкторы, смешение стилей языков C и C++ при управлении свободной памятью может привести к катастрофе. Для расширения буферов обычно используется функция

realloc
.

int max = 1000;

int count = 0;

int c;

char* p = (char*)malloc(max);

while ((c=getchar)!=EOF) { /* чтение: игнорируются символы

в конце файла */

if (count==max–1) { /* необходимо расширить буфер */

max += max; /* удвоить размер буфера */

p = (char*)realloc(p,max);

if (p==0) quit;

}

p[count++] = c;

}

Объяснения операторов ввода в языке С приведены в разделах 27.6.2 и Б.10.2.

Функция
realloc
может выделить память на прежнем участке, а может и перенести его содержимое во вновь выделенную область памяти. Даже не думайте применять функцию
realloc
к области памяти, выделенной с помощью оператора
new
.

Используя стандартную библиотеку языка C++, этот код можно переписать примерно так:

Поделиться:
Популярные книги

Газлайтер. Том 8

Володин Григорий
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 8

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Охота на попаданку. Бракованная жена

Герр Ольга
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Охота на попаданку. Бракованная жена

Кай из рода красных драконов

Бэд Кристиан
1. Красная кость
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Кай из рода красных драконов

Хозяйка Проклятой Пустоши. Книга 2

Белецкая Наталья
2. Хозяйка Проклятой Пустоши
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка Проклятой Пустоши. Книга 2

Безумный Макс. Поручик Империи

Ланцов Михаил Алексеевич
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Безумный Макс. Поручик Империи

Потусторонний. Книга 2

Погуляй Юрий Александрович
2. Господин Артемьев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Потусторонний. Книга 2

Чапаев и пустота

Пелевин Виктор Олегович
Проза:
современная проза
8.39
рейтинг книги
Чапаев и пустота

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Лютая

Шёпот Светлана Богдановна
Любовные романы:
любовно-фантастические романы
6.40
рейтинг книги
Лютая

Ведьмак (большой сборник)

Сапковский Анджей
Ведьмак
Фантастика:
фэнтези
9.29
рейтинг книги
Ведьмак (большой сборник)

Наследие Маозари 4

Панежин Евгений
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 4

Ученик

Губарев Алексей
1. Тай Фун
Фантастика:
фэнтези
5.00
рейтинг книги
Ученик

Начальник милиции. Книга 5

Дамиров Рафаэль
5. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции. Книга 5