Если «а» точек действительный блок памяти (от предыдущего таНос/перераспределить/calloc), то перераспределить вызов будет пытаться обеспечить блок памяти с новым размером запрошенной
Вызов перераспределить должен быть формы *tmp = realloc (a ...
возвращаемое значение перераспределить должны быть проверены
Если NULL, перераспределить не смог выделить требуемую память, и это оставляет «а» в качестве действительного указателя
Вы тогда ответственны за обработку любые данные, на которые указывает «a» (сохранить его/отменить), и вы несете ответственность за free
в памяти, на которую указывает «a»
Если вызов realloc был успешным, сделайте b = tmp
, и теперь «b» - новый указатель на блок памяти - не имеет значения, совпадает ли начальное местоположение с «a» или другим. «a» больше не является допустимым указателем на выделение памяти, хотя дальнейшие ошибки будут зависеть от того, указывает ли «a» на память, принадлежащую вашей программе, или нет - в основном, если a == b, 'a' можно получить без очевидных ошибок.
После действительного *tmp = realloc(a ...
& b = tmp;
:
1) Если начальное местоположение перераспределяются памяти осталась неизменной: (а == б)
выделит требуемую память
, но запустить его под Valgrind и вы сообщения об ошибках:
Invalid свободный()/удалить/удалить []/перераспределить()
Адрес 0x51fc040 составляет 0 байт внутри блока размером 256 free'd
в этом случае перераспределить не может освободить память, на которую указывает 'a'
и снова в этом случае «а» по-прежнему можно получить, как это указатель на память, которая выделяется на вашу проножку
2) Если начальное местоположение перераспределяются памяти было изменено: (а = Ь!)
она не будет выполнена, и Valgrind показывает вывод так:
адрес: 0x1e89010
адрес Ъ: 0x7f2c5893c010
A после перераспределить: 0x1e89010
ошибок в `./ test15 ': realloc(): недействительный старый размер: 0x0000000001e89010
и попытка доступа к «а» потерпит неудачу - даже попытка распечатать его значение в качестве указателя не удастся, по-видимому, потому, что он больше не указывает на память, принадлежащую программе
Другими словами, использование «a» после b = realloc(a ...
- это неопределенное поведение.
выше комментарий был основан на использование следующего кода:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *a = NULL, *b = NULL, *c = NULL;
/* initial allocation */
a = malloc(256);
if(a == NULL) return (1);
printf("address of a: %p\n", a);
/* reallocation 'b' MAY be same as 'a' - try much larger allocations */
void *tmp = realloc(a, 512);
if (!tmp) {
free(a);
return (1);
} else {
b = tmp;
}
printf("address of b: %p\n", b);
/* see what 'a' is now - this MAY crash the program*/
printf("a after realloc: %p\n", a);
/* 'a' may not be a valid pointer - try using it for another realloc */
c = realloc(a, 256);
/* Valgrind shows that memory could not be free'd or 'a' was not valid allocated memory */
printf("return value of c: %p\n", c);
if (c != NULL) {
free(c);
printf("'c' allocated\n");
} else {
free(b);
printf("'c' not allocated\n");
}
return 0;
}
чтение 'перераспределить()' спецификации и, возможно, Linux вручную или любое руководство. Поведение не совсем последовательное, это зависит. Кроме того, не делайте 'main()' вроде этого без возвращаемого типа 'int', это действительно старый и устаревший [tag: c]. –
C строго передается по значению! Как «realloc» даже сможет изменить указатель? – Olaf
@iharob: Я чувствую, что это непротиворечиво? Спецификация C очень понятна в отношении поведения. – Olaf