gpt4 book ai didi

c - 如何使用memcpy交换两个对象的部分?

转载 作者:行者123 更新时间:2023-12-04 06:31:05 26 4
gpt4 key购买 nike

我有两个相同类型的对象,例如:

typedef struct s_Object 
{
signed int a[3];
double float b;
unsigned short int c[30];
struct s_Object *next,
*prev;
} t_Object;
t_Object A, B;

我需要一些通用功能,例如:
swap_vars(&A, &B);

这将 不是交换指针而是所有其他数据 对象可以包含。在C中可能吗?

假设指针放在最高地址,我的第一个想法是:
void swap_vars(t_Object *pA, t_Object *pB){
t_Object C;
memcpy(&C, pA, sizeof(t_Object)-sizeof(t_Object *)*2;
memcpy(pA, pB, sizeof(t_Object)-sizeof(t_Object *)*2;
memcpy(pB, &C, sizeof(t_Object)-sizeof(t_Object *)*2;
}

但我不知道它有多便携(或者根本不知道)?

我正在寻找最便携的解决方案。

最佳答案

使用 offsetof :

memcpy(&C, pA, offsetof(t_Object, next));

原因是 t_Object最后可能有填充,所以如果你复制除了最后 8 个字节之外的所有字节,你可能会复制部分或全部指针。

我不确定这是否严格符合 - 标准说你可以复制整个对象,但我不确定它对对象的部分是什么意思。

会有点奇怪,但是想象一下,这个结构体中间有一些填充,最后有一些,并且实现用相同的字节值填充每个对象中的所有填充,随机选择,然后检查以查看填充仍然是一致的。我不认为这是禁止的。那么这行不通。

然而,在实践中,这是非常便携的。特别是,成员必须按照定义的顺序出现,所以 offsetof(t_Object, next)当然捕获对象的一部分(但不包括)指针。

如果您能够更改结构,那么您可以从交换部分和未交换部分构建它:
typedef struct payload {
signed int a[3];
double float b;
unsigned short int c[30];
} payload;

typedef struct s_Object {
payload data;
struct s_Object *next, *prev;
} t_Object;

交换则是:
payload C = pA->data;
pA->data = pB->data;
pB->data = C;

编辑:提示 memcpy vs assignment in C -- should be memmove?

后者还有一个优点,即在 pA == pB 时标准保证工作。 .与 memcpy 的那个不是,因为对于第二个副本,区域重叠。对于自交换的情况,两者都不是最佳选择,但一般来说,这些可能非常罕见,以至于如果您不需要检查指针是不值得的。

关于c - 如何使用memcpy交换两个对象的部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5406130/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com