c - Memcpy 或结构赋值?

标签 c struct memcpy memory-alignment

我有以下代码,不确定是使用结构对齐还是 memcpy 将结构 A 复制到自定义“堆栈”字符/字节数组。

以下两个代码选项有什么优点/缺点,或者有什么明显错误的地方吗?

必要的结构/函数。

struct B {
    int type;
    struct B *prev;
}

struct A {
    struct B base;
    int n;
    struct B *another;
    char name[1]; /* Struct hack */
};

void align(char **ptr, int n) {
    intptr_t addr = (intptr_t)*ptr;
    if(addr % n != 0) {
        addr += n - addr % n;
        *ptr = (char *)addr;
    }
}

选项 1:结构赋值

void struct_assignment() {
    char *stack = malloc(400*1000);
    char *top_of_stack = stack + 3149; /* Just an example */

    struct A *var = (struct A *)top_of_stack;
    align((char **)&var, sizeof(struct B)); /* Most restrictive alignment member in struct A */
    var->base.type = 1;
    var->base.prev = NULL;
    var->another = (struct base *)var;
    char *name = "test";
    var->n = strlen(name) + 1;
    strcpy(var->name, name);

    top_of_stack = (char*)var + sizeof(*var)+ (var->n - 1); /* -1 for name[1] */
}

选项2:memcpy

void memcpying() {
    char *stack = malloc(400*1000);
    char *top_of_stack = stack + 3149; /* Just an example */

    struct A var;
    var.base.type = 1;
    var.base.prev = NULL;
    var.another = NULL;
    char *name = "test";
    var.n = strlen(name) + 1;
    strcpy(var.name, name);

    char *aligned_ptr = top_of_stack;
    align(&aligned_ptr, sizeof(struct B)); /* Most restrictive alignment member in struct A */

    memcpy(aligned_ptr, &var, sizeof(var) + (var.n - 1); /* -1 for name[1] */
    struct A *var_ptr = (struct A*)aligned_ptr;
    var_ptr->another = (struct B *)var_ptr;

    top_of_stack = aligned_ptr + sizeof(var)+ (var.n - 1); /* -1 for name[1] */
}

选项 1 甚至是结构赋值吗?

这两个选项会导致相同的填充和对齐吗?

目标架构的字节顺序是否会影响选项 1?

最佳答案

我认为这不能称为struct 赋值。您正在分配给各个字段。

struct 在您只对“保留”的堆栈上对象的初始化感兴趣的情况下,assingment 可以使用临时的:

struct base tmp = {
       .type = 1,
       .prev = NULL,
       // whatever other fields you want to initialize
};
var->base = tmp;

或者使用复合字面量更简洁:

var->base = (struct base){
       .type = 1,
       .prev = NULL,
       // whatever other fields you want to initialize
};

这两种方法都具有初始化所有字段的优点 可能忘记了 0。对于复制操作本身,让编译器选择编译器设计者认为合适的任何内容。除非一些仔细的基准测试告诉您确实存在问题,否则不要乱搞这些事情。

关于c - Memcpy 或结构赋值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19233144/

相关文章:

c - 结构体定义

c# - 为什么编译器为 "yield"生成的枚举器不是结构?

c++ - 新的没有分配足够的内存?

c++ - 如何使用movntdqa避免缓存污染?

c++ - Memcpy 实现,严格别名

php - 为什么libcurl会计算 "4 TIMES"添加easy handles的个数?

c - 均衡后如何避免音频样本16位削波?

C-MPI 发送创建的带有字符数组的 typedef 结构

c - 将 ping 命令的输出写入 c 中的文本文件的问题?

c - 这个 strcmp() 有什么问题吗?