Как обновить другие указатели, когда realloc перемещает блок памяти? - PullRequest
19 голосов
/ 31 января 2010

Ссылка на realloc гласит:

Функция может перемещать блок памяти на новое место, в этом случае новое местоположение возвращается.

Означает ли это, что если я сделаю это:

void foo() {

        void* ptr = malloc( 1024 );

        unsigned char* cptr = ( unsigned char* )ptr+256;

        ptr = realloc( ptr, 4096 );
}

тогда cptr может стать недействительным, если realloc переместит блок?

Если да, то пересылает ли realloc каким-либо образом, что он переместит блок, чтобы я мог что-то сделать, чтобы предотвратить превращение cptr в недействительный?

Ответы [ 5 ]

7 голосов
/ 31 января 2010

Да, cptr станет недействительным, поскольку realloc перемещает блок! И нет, нет никаких упоминаний о том, что вам нужно сказать, что он перемещает блок памяти. Кстати, ваш код выглядит ненадежно ... читайте дальше ... пожалуйста, посмотрите мой ответ на другой вопрос и внимательно прочитайте код о том, как он использует 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;

Редактировать: Спасибо Защищено за указание гремлина, который закрался, когда я набирал это ранее.

4 голосов
/ 05 октября 2010

Это немного запаздывает, но решение этой проблемы (о которой никто не упомянул) - не использовать указатели на выделенные блоки, которые нужно будет распределить. Вместо этого используйте целочисленные смещения из базового указателя или (лучше) используйте тип struct и элементы-члены для адресации определенных мест в выделенном объекте.

4 голосов
/ 31 января 2010

Да, cptr станет недействительным, если realloc переместит блок.

Нет, сигнала нет. Вам нужно будет сравнить возвращаемое значение с исходным ptr местоположением.

3 голосов
/ 31 января 2010

Да.

Лучше всего сравнить ptr до и после перераспределения и посмотреть, было ли оно перемещено. Вы не должны назначать указатель на значение смещения, вместо этого вы должны сохранить смещение и затем индексировать оригинальный оператор с ним.

т.е.

вместо void* newPtr = ptr + 10; *newPtr = something;

Использование int new = 10; ptr[new] = something;

2 голосов
/ 31 января 2010

Да, cptr становится недействительным, если realloc перемещает блок.

...