Как переместить аргументы в динамически выделенную память? - PullRequest
0 голосов
/ 18 апреля 2019

Мне трудно понять, как работать с указателями памяти.У меня есть два указателя (имя, адрес, необязательныйInfo), который указывает на ранее выделенную myMemory.Размер этих строк может варьироваться.Они хранятся в myMemory следующим образом:

-------------------------------------------------------------------
| int ID 4Bytes | name 6bytes | adress 8Bytes| optionalInfo 8Bytes|
-------------------------------------------------------------------

Допустим, мне нужно увеличить или уменьшить размер имени и изменить его.Как я могу правильно использовать realloc, чтобы не потерять любую информацию, которую я хочу?Как я могу переместить мои аргументы в памяти, чтобы освободить место для нового имени?Мне нужно использовать наименьшее количество памяти.

Это моя структура, запрещается изменять ее.

struct myStruct{
    char* name;
    char* adress;
    char* optionalInfo;
    void* myMemory;
};

РЕДАКТИРОВАТЬ: Размер myMemory известен.Имя, адрес и optionInfo в этой структуре являются указателями на строки, хранящиеся в myMemory

1 Ответ

0 голосов
/ 19 апреля 2019

Давайте рассмотрим вопрос с точки зрения этой схемы памяти ...

-------------------------------------------------------------------
| 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;
}
...