Скопируйте две структуры в C, которые содержат символьные указатели

Что стандартный путь состоит в том, чтобы скопировать две структуры, которые содержат массивы символов?

Вот некоторый код:

#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 для каждого участника?

12
задан Peter Mortensen 17 December 2017 в 09:11
поделиться

4 ответа

У вас нет другого выбора, кроме как предоставить функцию копирования самостоятельно:

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 ++.

13
ответ дан 2 December 2019 в 06:44
поделиться

Да, копирование структуры, содержащей char arrays, будет работать без каких-либо проблем, но структуру с char указателями (или любым типом указателя, если на то пошло) вам придется делать вручную.

Также обратите внимание, что отливка возвращаемого типа malloc не нужна в C (она есть в C++) и может скрыть отсутствующий прототип для malloc.

7
ответ дан 2 December 2019 в 06:44
поделиться

Вы должны выделить память для любого указателя, если вы хотите сделать копию. Однако вы всегда можете указать указатель на уже выделенную память. Например, вы можете сделать следующее:

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 .

Было бы иначе, если бы членами были массивы символов.

1
ответ дан 2 December 2019 в 06:44
поделиться

Немного нестандартного мышления:

Поскольку структура вашей структуры статична, вы можете написать небольшую программу-утилиту или скрипт, который будет генерировать код копирования для вас.

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

Это быстро, и я не знаю, можно ли было бы быстрее просто написать код копирования вручную - но, по крайней мере, это более интересная проблема.

1
ответ дан 2 December 2019 в 06:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: