#c #memcpy #offsetof
#c #memcpy #смещение
Вопрос:
Я хотел бы скопировать часть структуры, начиная с определенного элемента, путем объединения offsetof
макроса и memcpy
, как показано ниже:
#include <stdio.h>
#include <string.h>
#include <stddef.h>
struct test {
int x, y, z;
};
int main() {
struct test a = { 1, 2, 3 };
struct test b = { 4, 5, 6 };
const size_t yOffset = offsetof(struct test, y);
memcpy(amp;b yOffset, amp;a yOffset, sizeof(struct test) - yOffset);
printf("%d ", b.x);
printf("%d ", b.y);
printf("%d", b.z);
return 0;
}
Я ожидал, что это выведет, 4 2 3
но на самом деле выводится 4 5 6
так, как будто никакого копирования не было. В чем я ошибся?
Комментарии:
1. Пожалуйста, объясните ваше понимание / намерение каждой части
memcpy(amp;b yOffset, amp;a yOffset, sizeof(struct test) - yOffset);
.2. Помните, что для любого указателя или массива
p
и индексаi
выражение*(p i)
равноp[i]
. Из этого следует, чтоamp;b yOffset
фактически равно(amp;b)[yOffset]
. Это означает, что вы выходите за пределы своих структур. Вместо этого вы должны использовать указатели «байт».3. Что касается «проблемы» и желаемого решения, какова актуальная проблема? Почему вам нужно копировать только часть структур? Почему вы думаете, что это лучшее (или единственное) решение вашей реальной основной проблемы?
4. Я думаю, что некоторые подразумевают, что мы смотрим на meta.stackexchange.com/questions/66377/what-is-the-xy-problem
5. @Someprogrammerdude Я читаю объектно-ориентированный C Акселя-Тобиаса Шрайнера, он делает что-то подобное для его реализации в vtable, но я не смог заставить его работать. Он на самом деле показывает кастинг в своей книге, но, честно говоря, я наивно проигнорировал это, думая, что это какой-то пережиток какой-то древней версии C. Мой плохой.
Ответ №1:
Вы выполняете арифметику указателя для указателя неправильного типа и записываете данные в некоторую случайную память в стеке.
Поскольку вы хотите вычислить смещения в байтах, вы должны использовать указатель на символьный тип. Так, например
memcpy((char *)amp;b yOffset,
(const char *)amp;a yOffset,
sizeof(struct test) - yOffset);