Функции библиотеки C -realloc()
Стандартная библиотека C - <stdlib.h>
realloc() — это функция стандартной библиотеки C, используемая для перераспределения памяти. Она очень важна в динамическом управлении памятью, особенно когда нужно изменить размер выделенной памяти.
Функции библиотеки Cvoid *realloc(void *ptr, size_t size)Попытка изменить размер перед вызовомmallocилиcallocВыделенныйptrРазмер блока памяти, на который указывает.
Объявление
Ниже приведено объявление функции realloc():
void *realloc(void *ptr, size_t size)
Параметр
- ptr-- ptr указывает на блок памяти, который нужно перераспределить, ранее выделенный вызовом malloc, calloc или realloc. Если это нулевой указатель, будет выделен новый блок памяти, и функция вернёт указатель на него.
- size-- Новый размер блока памяти в байтах. Если размер равен 0 и ptr указывает на существующий блок памяти, блок памяти, на который указывает ptr, освобождается, и возвращается нулевой указатель.
Возвращаемое значение
- В случае успеха,
realloc()Возвращает указатель на новый блок памяти. - В случае неудачи возвращает
NULL, а исходный блок памяти остаётся неизменным (не освобождается).
Инструкция по использованию
realloc()Он может переместить блок памяти в новое местоположение (если в исходном местоположении недостаточно места, чтобы вместить новый размер). Если перемещение успешно,ptrон будет указывать на новое местоположение. Следует обратить особое внимание: старыйptrУказатель необходимо обновить наrealloc()возвращённый новый адрес.- Если выделение памяти не удалось,
realloc()returnNULL, а исходный блок памяти не освобождается. Чтобы избежать утечек памяти, следует использовать временный указатель для полученияrealloc()возвращаемого значения и проверить, является ли оноNULL。
Пример
В следующем примере демонстрируется использование функции realloc().
Пример 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *str;
/*Начальное выделение памяти*/
str = (char *) malloc(15);
strcpy(str, "example");
printf("String = %s, Address = %p\n", str, str);
/*Перераспределение памяти*/
str = (char *) realloc(str, 25);
strcat(str, ".com");
printf("String = %s, Address = %p\n", str, str);
free(str);
return(0);
}
Давайте скомпилируем и запустим приведённую выше программу, которая выдаст следующий результат:
String = example, Address = 0x7fa2f8c02b10 String = example.com, Address = 0x7fa2f8c02b10
Пример 2
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = malloc(5 * sizeof(int)); // Выделить память для 5 целых чисел
if (arr == NULL) {
printf("Не удалось выделить память\n");
return 1;
}
// Заполнить массив
for (int i = 0; i < 5; i++) {
arr[i] = i * 2;
}
// Перераспределить память для хранения 10 целых чисел
int *new_arr = realloc(arr, 10 * sizeof(int));
if (new_arr == NULL) {
printf("Перераспределение памяти не удалось\n");
free(arr); // Освободить исходную память при ошибке
return 1;
}
// Заполнить новую часть
for (int i = 5; i < 10; i++) {
new_arr[i] = i * 2;
}
// Вывести новый массив
for (int i = 0; i < 10; i++) {
printf("%d ", new_arr[i]);
}
free(new_arr); // Наконец, освободите память
return 0;
}
#include <stdlib.h>
int main() {
int *arr = malloc(5 * sizeof(int)); // Выделить память для 5 целых чисел
if (arr == NULL) {
printf("Не удалось выделить память\n");
return 1;
}
// Заполнить массив
for (int i = 0; i < 5; i++) {
arr[i] = i * 2;
}
// Перераспределить память для хранения 10 целых чисел
int *new_arr = realloc(arr, 10 * sizeof(int));
if (new_arr == NULL) {
printf("Перераспределение памяти не удалось\n");
free(arr); // Освободить исходную память при ошибке
return 1;
}
// Заполнить новую часть
for (int i = 5; i < 10; i++) {
new_arr[i] = i * 2;
}
// Вывести новый массив
for (int i = 0; i < 10; i++) {
printf("%d ", new_arr[i]);
}
free(new_arr); // Наконец, освободите память
return 0;
}
Примечания
- Проверьте возвращаемое значение: Всегда проверяйте
realloc()возвращаемое значение. Если оно возвращаетNULL, не отбрасывайте напрямую исходный указатель. - Утечка памяти: если
realloc()returnNULL, исходный блок памяти не будет освобожден. В этот момент исходную память следует освободить и выполнить обработку ошибок. - Инвалидация указателя: Если вы напрямую используете исходный указатель для получения
realloc()возвращаемый новый указатель, что может привести к утечкам памяти, особенно когдаrealloc()это не удается. Поэтому обычно сначала используют временный указатель для получения возвращаемого значения.
Типичные применения
- Динамически расширять размер массивов или других структур данных.
- Используется для обработки наборов данных переменного размера во время выполнения, таких как динамически генерируемые списки, строки или кэши и т. д.