Давайте рассмотрим вопрос с точки зрения этой схемы памяти ...
-------------------------------------------------------------------
| int ID 4Bytes | name 6bytes | adress 8Bytes| optionalInfo 8Bytes|
-------------------------------------------------------------------
... игнорируя, как это может относиться к членам struct myStruct
, отличным от myMemory
.
Допустим, мне нужно увеличить или уменьшить размер имени и изменить его.Как я могу правильно использовать realloc, чтобы не потерять какую-либо информацию, которую я хочу?
До тех пор, пока вы realloc
достигнете размера, по крайней мере, такого размера, который уже занимает данные, данные не будут потеряныперераспределение.Также ни один не будет перемещен относительно начального адреса блока.Обратите внимание, однако, что перераспределенный блок может находиться в другом месте, чем исходный, и если это так, то исходный блок будет освобожден, и доступ к нему больше не требуется.
Как я могу переместить мои аргументы в памяти, чтобы освободить место для нового имени?
Самым очевидным инструментом для этой работы будет функция memmove()
.Итак, предположим, что вы хотите увеличить размер области, помеченной как «имя», с 6 байтов, скажем, до 10 байтов, не перезаписывая другие данные, сначала вам нужно перераспределить:
void *temp = realloc(x.myMemory, old_size + 4);
Поскольку realloc()
не гарантирует успеха, вы не должны обновлять указатель x.myMemory
до тех пор, пока не добьетесь успеха:
if (temp) { // if temp is non-null
Затем вы можете сместить адрес и дополнительные данные в пределах большего пространства наосвободите место для дополнительной информации об имени:
memmove(((char *)temp) + new_offset_of_address_data,
((char *)temp) + old_offset_of_address_data,
combined_size_of_address_and_optionalInfo_data);
Приведения к типу char *
необходимы, поскольку арифметика указателей определяется в единицах типа указываемого типа и, следовательно, вообще не определяется для указателей.на void
.
Не забудьте назначить новый указатель для вашей структуры:
x.myMemory = temp;
}