首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用memcpy()进行结构复制是否合法?

使用memcpy()进行结构复制是否合法?
EN

Stack Overflow用户
提问于 2019-08-24 14:50:15
回答 2查看 498关注 0票数 3

假设我有两个结构:

代码语言:javascript
复制
typedef struct {
    uint64_t type;
    void(*dealloc)(void*);
} generic_t;

typedef struct {
    uint64_t type;
    void(*dealloc)(void*);
    void* sth_else;
} specific_t;

复制到简单结构的常见方法是:

代码语言:javascript
复制
specific_t a = /* some code */;
generic_t b = *(generic_t*)&a;

但这是非法的,因为它违反了严格的别名规则。

但是,如果我的memcpy结构I只有不受严格别名规则影响的void指针:

代码语言:javascript
复制
extern void *memcpy(void *restrict dst, const void *restrict src, size_t n);

specific_t a = /* some code */;
generic_t b;
memcpy(&b, &a, sizeof(b));

用这样的memcpy复制一个结构是合法的吗?

一个示例用例将是一个通用的释放程序:

代码语言:javascript
复制
void dealloc_any(void* some_specific_struct) {
    // Get the deallocator
    generic_t b;
    memcpy(&b, some_specific_struct, sizeof(b));

    // Call the deallocator with the struct to deallocate
    b.dealloc(some_specific_struct);
}

specific_t a = /* some code */;
dealloc_any(&a);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-24 15:45:49

合法的。根据memcpy手册: memcpy()函数将n个字节从内存区域src复制到内存区域dest。内存区域不能重叠。如果内存区域确实重叠,请使用memmove(3)。

所以它根本不关心类型。它只是按照你说的去做。因此,请谨慎使用它,如果您使用了some (A)而不是sizeof(b),您可能已经覆盖了堆栈上的其他一些变量。

票数 3
EN

Stack Overflow用户

发布于 2019-08-24 15:04:49

虽然这不是一个直接的答案,但可能会有所帮助。

如果您想要重叠的struct,可以使用union

代码语言:javascript
复制
typedef union
{
    generic_t  generic;
    specific_t specific;
} combined_t;

这就避免了转换的需要。但是,您需要非常小心,以确保您没有访问sth_else,如果它没有初始化。您需要数据和逻辑来确定设置了哪些union成员以及访问函数/宏。这正致力于在C中构建类继承。

在过去,我在C中构建了一个类似Java的异常处理机制(so trycatch,.)。这具有链接时异常“类”继承的特点。因此,编译后的库可以定义一个SomeException 'class',然后用户代码可以‘子类’这个异常,新的‘子类’异常仍然会被一个SomeException catch子句捕获。如果您需要停留在C中,那么您可以使用智能宏和一些精心选择的简单的C结构来做很多事情。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57639016

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档