Что стандартный путь состоит в том, чтобы скопировать две структуры, которые содержат массивы символов?
Вот некоторый код:
#include stdio.h>
#include string.h>
#include stdlib.h>
typedef struct {
char* name;
char* surname;
} person;
int main(void){
person p1;
person p2;
p1.name = (char*)malloc(5);
p1.surname = (char*)malloc(5);
strcpy(p1.name, "AAAA");
strcpy(p1.surname, "BBBB");
memcpy(&p2, &p1, sizeof(person));
free(p1.name);
printf("%s\n", p2.name);
return 0;
}
Строка printf("%s\n", p2.name);
не печатает что-то, потому что я освободил буфер.
Проблема с моими структурами состоит в том, что они больше, чем структура person
. Они содержат сотни символьных указателей, и я должен скопировать каждого участника один за другим.
Есть ли другой способ скопировать две структуры, которые содержат массивы символов без использования malloc
и strcpy
для каждого участника?
У вас нет другого выбора, кроме как предоставить функцию копирования самостоятельно:
void copy_person(person *dst, const person *src)
{
dst->name = malloc(strlen(src->name) + 1);
dst->surname = malloc(strlen(src->surname) + 1);
strcpy(dst->name, src->name);
strcpy(dst->surname, src->surname);
}
, которая может быть более сложной, чем это: проверка на наличие ошибок, факторизация strlen + strcpy
во вспомогательной функции и т. д.
Для этого нужны конструкторы копирования в C ++.
Да, копирование структуры, содержащей char arrays, будет работать без каких-либо проблем, но структуру с char указателями (или любым типом указателя, если на то пошло) вам придется делать вручную.
Также обратите внимание, что отливка возвращаемого типа malloc не нужна в C (она есть в C++) и может скрыть отсутствующий прототип для malloc.
Вы должны выделить память для любого указателя, если вы хотите сделать копию. Однако вы всегда можете указать указатель на уже выделенную память. Например, вы можете сделать следующее:
p2.name = p1.name (p1.name is already allocated memory)
Это опасно , поскольку существует более одной ссылки на одну и ту же ячейку памяти. Если вы освободите p1.name
или p2.name
, это приведет к опасной ситуации.
Чтобы скопировать весь контент, вы должны выделить память указателям структуры p2.
p2.name = <allocate memory>
Copy individual struct members instead of a memcpy of the entire struct
Это связано с тем, что память не выделяется непрерывно. Также sizeof (struct)
предоставит вам размер членов структуры, а не выделенную для нее память.
Например, sizeof (p2) = 8 = sizeof (p1) = sizeof (person)
даже после выделения памяти членам p1
.
Было бы иначе, если бы членами были массивы символов.
Немного нестандартного мышления:
Поскольку структура вашей структуры статична, вы можете написать небольшую программу-утилиту или скрипт, который будет генерировать код копирования для вас.
Возьмите исходный код определения вашей структуры в качестве входных данных, а затем разработайте набор правил для генерации кода копирования.
Это быстро, и я не знаю, можно ли было бы быстрее просто написать код копирования вручную - но, по крайней мере, это более интересная проблема.