sem05 (1114913), страница 2
Текст из файла (страница 2)
Не гарантируется, что значения, записанные восвобождаемой области памяти, будут сохранены после вызова free. Вызов free(0) безопасен и не производит никаких действий.Функция free не требует параметра размера блока освобождаемой памяти, потому чторазмер блока памяти хранится в специальных структурах, поддерживаемых функциями работы с динамической памятью, непосредственно перед началом выделенного блока памяти. Поэтому запись за пределы выделенного блока, например, вследствие недостаточного контроля индексов массивов, может привести к разрушению служебной информациии краху программы. Как правило крах программы происходит при работе функций выделения или освобождения памяти. Поэтому, если Ваша програма завершилась с ошибкойSegmentation fault, и дамп стека показывает, что ошибка произошла, например, вфункции free, это не значит, что free реализована неверно, но где-то в Вашей программе есть ошибка, которая приводит к записи вовне выделенного блока памяти и разрушениюслужебных структур.void *realloc(void *ptr, size_t newsize);4изменяет размер выделенного блока памяти.
Если ptr == NULL, функция realloc работает в точности как malloc, а если newsize == 0, realloc работает как free. Иначефункция выделяет в динамической памяти блок размера newsize и копирует в него началоблока памяти по адресу ptr. Если новый блок больше старого, остаток памяти нового блока не инициализируется. Не гарантируется, что новый блок памяти будет начинаться с тогоже адреса памяти, что и предыдущий, даже если размер блока памяти был уменьшен. Послефункции realloc уже нельзя пользоваться старым блоком памяти, выделенным по адресуptr. Если невозможно выделить область памяти заданного размера, функция возвращаетнулевой указатель.
В этом случае область памяти по старому адресу ptr не изменяется ипо-прежнему доступна для использования.Функцию realloc можно использовать для реализации так называемых расширяемыхмассивов, то есть массивов, размер которых динамически увеличивается, когда очереднаяпорция данных в них не может поместиться.Рассмотрим следующий пример: на стандартном потоке ввода задаётся последовательность вещественных чисел. Ввод завершается концом файла. Необходимо распечатать настандартный поток вывода только числа, не превышающие среднего значения всех введённых чисел. Для хранения чисел мы будем использовать расширяемый массив.1234567891011121314151617181920212223242526272829#include <stdio.h>#include <stdlib.h>int main(void){int arr_a = 0, arr_u = 0, i;double *arr = 0;double s = 0, v;arr_a = 16;if (!(arr = (double*) malloc(arr_a * sizeof(arr[0]))))goto out_of_mem;while (scanf("%lf", &v) == 1) {if (arr_u == arr_a) {arr_a *= 2;if (!(arr = (double*) realloc(arr, arr_a * sizeof(arr[0]))))goto out_of_mem;}s += v;arr[arr_u] = v;arr_u++;}if (!arr_u) return 0;s /= arr_u;for (i = 0; i < arr_u; i++)if (arr[i] <= s) printf("%g\n", arr[i]);return 0;out_of_mem:fprintf(stderr, "memory exhausted\n");return 1;}51.3 Упражнения1.
Используя только указательную арифметику, то есть не использования операций индексирования массива и переменных-индексов, напишите функцию strlen с прототипом:int strlen(char *s1);2. Используя только указательную арифметику, то есть не использования операций индексирования массива и переменных-индексов, напишите функцию strspn с прототипом:int strspn(char *s1, char *s2);Функция просматривает строку s1 и находит в ней первый символ, который входит в строкуs2. Строка s2 рассматривается, как множество символов, которые ищутся в s1. Если поискзавершился успешно, функция должна вернуть индекс первого такого символа.
Если в строкеs1 нет символов из s2, функция возвращает -1.3. Напишите функциюchar *concat(char *s1, char *s2);которая конкатенирует строки s1 и s2 и возвращает указатель на строку-результат. Памятьпод строку-результат выделяется в куче.4. Напишите функциюchar *getline(void);которая считывает строку текста со стандартного потока ввода. Строка завершается символом’\n’ или признаком конца файла. В случае, если не считан ни один символ строки, и сразуполучен конец файла, возвращается 0.
Символ ’\n’ в строку не добавляется.5. С использованием функции getline напишите программу, которая печатает в обратном порядке строки текста на стандартном потоке ввода.6.