Как копировать структуры в си

Копирование элементов структуры

Меня больше смущают структуры. Есть много способов скопировать структуру.

Я сомневаюсь в копировании членной структуры. memcpy(&c1.real, &c2->real, sizeof(struct complex))

Я читал, что описанный выше метод небезопасен. Потому что это не сработает, если мы изменим порядок членов структуры. Никто не объяснил, как не безопасно? Это сбивает меня с толку, потому что обе переменные являются одинаковыми структурами, я указываю, что я хочу скопировать [в данном случае реально]. Тогда почему это небезопасно? может кто-нибудь объяснить это?

4 ответа

Кроме того, назначение является более высокоуровневым, поэтому более абстрактным и, следовательно, более компактным и более эффективным.

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

memcpy(&c1.real, &c2->real, sizeof(struct complex)) очень странно, так как типы ботов атомарны, в таком копировании нет необходимости. Также sizeof(struct complex) неверно, потому что оно должно было быть sizeof(int) (что составляет лишь половину размера всей конструкции) Достаточно простого задания:

Изменение порядка элементов структуры в этом случае не действует. Поля структуры явно указаны, как вы упомянули.

Когда все становится сложнее, легче ошибаться. Как вы это сделали:

Чем проще, тем лучше:

При использовании memcpy возникает еще одна проблема; вы теряете безопасность типов. Иногда вы этого хотите, но обычно не при работе с двумя объектами с одинаковым типом данных.

Если вы измените порядок полей следующим образом:

Источник

Скопировать структуру в структуру в C

Я хочу скопировать идентичную структуру в другую, а затем использовать ее как сравнение с первой. Дело в том, что мой компилятор дает мне предупреждение, когда я так делаю! Должен ли я сделать это по-другому или я делаю это неправильно:

ОТВЕТЫ

Ответ 1

Компилятор создаст код для копирования структуры для вас.

Ответ 2

Ваш код верен. Вы также можете назначить его непосредственно другому (см. ответ Йоахима Пилеборга).

Когда вы позже придете, чтобы сравнить две структуры, вам нужно быть осторожным, чтобы сравнивать структуры длинным образом, по одному члену за раз, вместо использования memcmp ; см. Как вы сравниваете структуры для равенства в C?

Ответ 3

Структура копирования в c вам просто нужно назначить значения следующим образом:

теперь RTCclkBuffert.hour будет иметь значение 5,

RTCclkBuffert.minute будет иметь значение 4

RTCclkBuffert.second будет иметь значение 3

Ответ 4

Ваш код memcpy верен.

Я предполагаю, что вам не хватает string.h. Поэтому компилятор предполагает неправильный прототип memcpy и, следовательно, предупреждение.

Во всяком случае, вам просто нужно назначить структуры для простоты (как указал Йоахим Пилеборг).

Ответ 5

memcpy ожидает, что первые два аргумента будут void *.

P.S. хотя это и не обязательно, соглашение диктует скобки для оператора sizeof. Вы можете уйти с большим количеством в C, что оставляет код невозможным для поддержания, поэтому следующая конвенция является признаком хорошего программиста C.

Ответ 6

Также хороший пример.

Ответ 7

Я думаю, вам нужно наложить указатели на (void *), чтобы избавиться от предупреждений.

Также вы используете sizeof без скобок, вы можете использовать это с переменными, но если RTCclk был определен как массив, sizeof of вернет полный размер массива. Если вы используете use sizeof с типом, вы должны использовать его с помощью скобок.

Источник

копирование данных из одной структуры в другую в C

Если у меня есть структура, определенная как:

И 2 переменные этого типа:

Я хочу перенести данные из image1 в данные image2(предполагая, что image1 имеет некоторые записанные данные, а image2 имеет данные, выделенные с помощью malloc или calloc). Как это можно сделать? Большое спасибо.

5 ответов

Я хочу скопировать данные из одной базы данных, которая имеет таблицу с именем domains, в другую базу данных, которая также имеет таблицу с именем domains. Я пытался сделать это с помощью phpmyadmin, но он не копируется, возможно, из-за значений Auto_increment. он просто не копируется в другой.

У меня есть заказной сайт, который я хочу перенести на коммерческое решение, которое кажется более надежным. Для примера предположим, что на сайте в настоящее время работает скрипт форума, сделанный студентом из A-Z, и цель состоит в том, чтобы перенести его, скажем, на vBulletin. Какой подход.

редактировать: Выделите данные для image2.data после этого вы должны strcpy(image2.data,image1.data), если данные null завершены, но если это не так, то используйте memcpy с размером данных.

Это просто в C.Simply сделать следующее(предполагая, что image2 неинициализирован):

Вы можете назначить одну структурную переменную другой, если они имеют один и тот же тип. Нет необходимости копировать фрагмент-meal.This является полезной функцией C.

Это уже обсуждалось ранее :

(предполагая, что в данных есть image1.width * image1.height байт, и в image2.data достаточно места malloc() для хранения этого.)

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

Я пытаюсь скопировать содержимое структуры в другую структуру того же типа. Однако я хотел бы иметь возможность изменять значения одной структуры, не влияя на другую позже. Я имею дело с чтением и.

В настоящее время у меня есть структура xml в приложении. Мне нужно было преобразовать его из одной структуры в другую. У меня есть xsd для этого. Приложение находится в C#. естественно, я думал.

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

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

Каков стандартный способ копирования данных из одной базы данных oracle в другую? 1) считывание данных из исходной таблицы и копирование в временную таблицу назначения с помощью конфигурации( т. е.

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

Я уже знал, что вот такой вопрос, как мой: PHP/MySQL: копирование таблицы и данных из одной базы данных в другую Но этот вопрос был задан около 4 лет назад, поэтому я хотел бы повторить его сегодня.

Источник

структуры в C

Table of Contents

1 Структура

Это совокупность нескольких переменных, часто различных типов, сгруппированных под единым именем для удобства обращения. Главное изменение, внесённое стандартом ANSI в работу со структурами, — это определение присваивания структур. Теперь структуры можно копировать, присваивать, передавать в функции и возвращать из функций.

Ключевое слово struct начинает объявление структуры, состоящее из списка объявлений элементов в фигурных скобках. После слова struct может стоять необязательный идентификатор, именуемый меткой структуры. Метка обозначает конкретный структурный тип; впоследствии её можно использовать для краткости, опуская всё, что находится в скобках при объявлении структур того же типа.

Переменные, перечисленные в объявлении структуры, называются её членами, элементами или полями. Элемент структуры или её метка может иметь то же имя, что и обыкновенная переменная безо всякого конфликта, поскольку они всегда отличаются по контексту.

Объявление со словом struct фактически вводит новый тип данных. Поэтому допустимо такое объявление переменных:

Данный код объявляет переменные \(x, y, z\) определённого именованного типа и выделяет для них место в памяти. Объявление структуры, после которого нет списка переменных, не выделяет никакой памяти для объектов, а просто описывает форму структуры. Так же можно объявлять переменные, используя метку структуры:

Структуру можно инициализировать, поставив после её определения список значений-констант:

Обращение к элементам структуры выполняется следующим образом:

Структуры можно вкладывать друг в друга:

1.1 Структуры и функции

Расширенными операциями над структурами являются копирование или присваивание структуры как целого, взятие её адреса операцией &, а так же обращение к её элементам. Копирование и присваивание включают также в себя передачу аргументов в функции и возвращение значений из функций. Структуры нельзя сравнивать между собой. Структуру можно инициализировать списком констант-инициализаторов для всех её полей.

Вместо того чтобы помещать результат во временную переменную, мы инкрементировали компоненты структуры p1, чтобы подчеркнуть тот факт, что параметры-структуры передаются по значениям, как и любые другие параметры.

Если в функцию необходимо передать большую структуру, это лучше сделать передав указатель на неё, а не копию всех её данных. Указатели на структуры обладают всеми свойстваи указателей на обычные переменные.

Указатели на структуры используются так часто, что для удобства записи ссылок по ним введено дополнительное обозначение: p->элемент-структуры

2 Массивы структур

3 typedef

Имя нового типа, объявляемое в typedef, стоит не сразу после ключевого слова, а на месте имени переменной. Синтаксически ключевое слово typedef можно считать аналогом идентификатора класса памяти: extern, static и т.п. Новые типы, определяемые с помощью typedef, начинаются с прописной буквы, чтобы можно было их легко различить.

Фактически, оператор typedef очень напоминает директиву #define с тем исключением, что, поскольку он анализируется компилятором, он может допускать такие текстовые подстановки, которые препроцессору не по силам. Например:

Здесь опеределяется тип PFI — «указатель на функцию от двух аргументов типа char*, возвращающую int». Этот тип можно использовать, например, таким образом:

4 Объединения

Это переменная, которая может содержать объекты различных типов и размеров (но не одновременно); при этом удовлетворение требований к размеру и выравниванию возлагается на компилятор. С помощью объединений можно работать с данными различных типов в пределах одного участка памяти, не привнося в программу элементы низкоуровневого, машинно-зависимого программирования.

Переменная u будет иметь достаточную длину, чтобы содержать данные самого длинного из трёх типов; конкретный размер зависит от системы и реализации. Переменной u можно присваивать данные любого типа, а затем использовать их в выражениях (строго по правилам работы с конкретным типом). Извлекать можно данные только того типа, который был помещён при последнем обращении к переменной. Следить и помнить, какие именно данные были помещены в объединение, — это забота программиста; если поместить значение одного типа, а извлечь его как значение другого, результат будет системно-зависимым и трудно предсказуемым.

Обращение к элементам объединения выполняется так же, как к элементам структуры:

Пусть в переменной \(utype\) хранится информация о типе данных, находящихся в текущий момент в объединении:

Объединения могут применяться в структурах и массивах, и наоборот. Способ обращения к члену объединения в структуре (или к члену структуры в объединении) полностью идентичен обращению к элементу вложенной структуры.

Фактически, объединение является структурой, в которой все элементы имеют нулевое смещение от её начала, сама она имеет достаточную длину, чтобы в неё поместился самый длинный элемент, и при этом выравнивание происходит правильно для всех типов данных в объединении. Над объединениями разрешено выполнять те же операции, что и над структурами: присваивать или копировать как единое целое, брать адрес и обращаться к отдельным элементам.

5 Битовые поля

Внутри системно-зависимой единицы памяти, которую мы будем называть «словом«, можно задать битовое поле (bit-field) — совокупность идущих подряд битов. Синтаксис определения и использования полей основан на структурах.

Данный код является заменой коду на константах:

В переменной flags содержится три однобитных поля. Число после двоеточия задаёт ширину поля в битах. Поля объявлены как unsigned int, чтобы гарантированно быть велечинами без знака. Практически всё, что связано с битовыми полями, является системно-зависимым. Например, только в конкретной реализации определяется, могут ли поля перекрывать границы слов. Поля не обязаны иметь имена; безымянные поля (двоеточия с размером после них) часто используются для пропуска и резервирования отдельных битов. Для принудительного выравнивания по границе следующего слова можно использовать специальное значение длины поля, равное \(0\). Совокупность полей — не массив, и у них нет адресов, поэтому операция & к ним неприменима.

Источник

Правильно копировать структуры C# с (байтовыми) массивами в них?

из того, что я понимаю, при назначении переменной struct другой, первый обычно копируется вместо создания ссылки:

это работает просто отлично, выход:

однако, если у меня есть байт[] внутри моей структуры, это поведение изменяется:

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

Edit: Спасибо за вашу помощь! Чтобы глубоко скопировать мою структуру, я теперь использую этот код:

это должно называться так:

это, кажется, работает нормально, хотя я знаю, что это грязный код.

однако, поскольку структуры, с которыми я работаю, имеют более 50 byte[] несколько другие структуры в них, это просто слишком много работы, чтобы писать Copy() / Clone() методы для каждого из них.

предложения по улучшению кода, конечно, очень приветствуются.

7 ответов

Я не могу найти ссылку, но во втором случае вы просто копируете адрес массива, а не весь массив.

вам нужно сделать глубокую копию, где вы также копируете содержимое массива.

вам придется создать Clone способ, чтобы сделать глубокую копию членов структуры:

вот перегрузка для вашего метода копирования структуры, которая не требует приведения результатов:

вы называете это так:

вы даже можете использовать var :

Если вы хотите, чтобы структура инкапсулировала массив по значению (или, по крайней мере, вела себя так, как будто это так), так что копирование структуры будет копировать массив, у вас есть четыре варианта, которые я вижу:

подход #4 С соответственно-объект проектирования-держатель класса может достичь o(LG с(Н)) для операций чтения и записи выполняются в произвольной последовательности, или, может быть, удастся достичь O(1) производительность для чтения и записи, выполняемых в определенной закономерности (например, «написать» способ может просто добавить каждого индекса и значением для связанного списка обновлений пока либо количество обновлений превышает размер массива или попытке чтения элемента, а затем создать новый массив со всеми обновлениями; такой класс будет работать медленно, если он был попеременно читал и писал, но общее время выполнения П обновления Далее следуют N говорится будет о(n), т. е. среднее время на обновление или чтение будет O(1).

да, но byte[] является ссылочным типом. Следовательно, в структуре хранится только ссылка (указатель) (структура является типом значения). При копировании структуры копируется только ссылка.

вам нужно создать новый byte[] и скопировать данные.

скопировать все byte[] в классе вы можете использовать отражение.

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

один умнее решение, заимствованные из здесь:

помимо безопасности типа из-за использования шаблона, а также сохранения двух функций, это требует, чтобы связать SerializableAttribute на struct s( или классы); CLR-aware двоичная (de) сериализация намного лучше, чем слепое копирование необработанных байтов, я думаю:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *