Простой вопрос на C: копирование переменных определенного пользователем типа структуры - PullRequest
2 голосов
/ 01 сентября 2010

Это должно быть просто. Скажем, у нас есть структура из библиотеки, которая не предлагает возможности копирования. Есть ли простой способ скопировать переменную типа этой структуры в новую переменную того же типа без выполнения присваиваний для каждого из ее подэлементов? Или нужно делать специальные функции копирования?

Ответы [ 6 ]

8 голосов
/ 01 сентября 2010

Ну, типы структур могут быть назначены в C:

struct SomeStruct s, d;
...
d = s;

Не имеет значения, где они определены.И нет необходимости копировать «каждый из подчиненных».Откуда вы вообще взяли идею о копировании его по элементам?

Конечно, задание будет выполнять только поверхностное копирование.Если вам нужно глубокое копирование, вам нужна процедура копирования, предоставляемая библиотекой.Если его нет, вам придется реализовать его самостоятельно.Для этого вам понадобятся полные знания о фактической организации структуры с большой памятью.Если вы этого не знаете (т.е. если это не задокументировано), вам не повезло - правильное глубокое копирование невозможно.

3 голосов
/ 01 сентября 2010

Это звучит как тема классического глубокого копирования или мелкого копирования.

Вы можете скопировать переменную (поверхностное копирование) с помощью операции memcpy.

Если структура содержит ссылки на другие переменные, этого может быть недостаточно, и вам следует реализовать более изощренную (глубокую) копию.

2 голосов
/ 01 сентября 2010

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

Например:

typedef struct {
    char data[100];
} string;

string a = {"Hello world!"};
string b;

b = a; // works!

puts(b.data); // writes "Hello world!" to standard out.

b.data = a.data; // oops, doesn't work!
2 голосов
/ 01 сентября 2010

C изначально поддерживает присвоение структуры, поэтому, если копия для каждого члена является безопасной / эффективной, вы можете просто использовать прямое назначение:

typedef struct { 
    int v1, v2;
    float f1;
} A;

A a = { 0, 2, 1.5f };

A b;
b = a;
1 голос
/ 01 сентября 2010

Имейте в виду, что создание структуры для каждого члена может быть небезопасным;например, он может содержать указатели, и простое копирование этих указателей может быть плохой идеей, если вам нужна фактическая копия данных. Однако , когда является безопасным для этого, вы можете использовать memcpy, чтобы сэкономить несколько нажатий клавиш.

struct foo a, b;

// let the third-party lib fill the struct
thirdPartyLibraryCallInvolvingTheFooStruct(&a);

// now we want to copy a to b
memcpy(&b, &a, sizeof b);

Не забудьте прочитайте man-страницу для получения дополнительной информации!

0 голосов
/ 01 сентября 2010

Вы можете использовать функцию memcpy . Это устанавливает непрерывную область памяти, просто копируя бит за битом; игнорируя, является ли это последовательность целых чисел, или массив символов, или что-то еще.

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