Как обновить другие указатели, когда realloc перемещает блок памяти?
Ссылка realloc говорит:
Функция может перемещать блок памяти на новое место, и в этом случае новое местоположение возвращается.
Означает ли это, что если я это сделаю:
void foo() {
void* ptr = malloc( 1024 );
unsigned char* cptr = ( unsigned char* )ptr+256;
ptr = realloc( ptr, 4096 );
}
то cptr может стать недействительным, если realloc перемещает блок?
Если да, то каким-либо образом передается сигнал realloc, чтобы он перемещал блок, чтобы я мог что-то сделать, чтобы предотвратить cptr недействительным?
Ответы
Ответ 1
Да, cptr
станет недействительным, так как realloc перемещает блок! И нет, нет упоминания о том, что вы сигнализируете о том, что он перемещает блок памяти. Кстати, ваш код выглядит iffy... читайте дальше... см. Мой ответ на другой вопрос и очень внимательно прочитайте код о том, как он использует realloc
, Общий консенсус заключается в том, если вы это сделаете:
void *ptr = malloc(1024);
/* later on in the code */
ptr = realloc(ptr, 4096);
/* BAM! if realloc failed, your precious memory is stuffed! */
Способ обойти это - использовать временный указатель и использовать его, как показано:
void *ptr = malloc(1024);
/* later on in the code */
void *tmp = realloc(ptr, 4096);
if (tmp != null) ptr = tmp;
Изменить: Спасибо Secure за то, что указали на гремлин, который закрался, когда я печатал это раньше.
Ответ 2
Да, cptr
станет недействительным, если realloc перемещает блок.
Нет, сигнала нет. Вам нужно будет проверить возвращаемое значение в исходном местоположении ptr
.
Ответ 3
Это немного поздно, но решение этой проблемы (о которой никто не упомянул) заключается не в том, чтобы использовать указатели в выделенные блоки, которые нужно будет выделить. Вместо этого используйте целочисленные значения смещения от базового указателя или (лучше) используйте типы struct
и элементы-члены для адресации определенных местоположений в выделенном объекте.
Ответ 4
Да.
Лучше всего сравнить с ptr до и после перераспределения и посмотреть, была ли она перенесена. Вы не должны назначать указатель на значение смещения, вместо этого вы должны хранить смещение, а затем индексировать его с помощью оператора.
то есть.
Вместо
void* newPtr = ptr + 10;
*newPtr = something;
Использование
int new = 10;
ptr[new] = something;
Ответ 5
Да, cptr становится недействительным, если realloc перемещает блок.