在这种情况下,在结构体中使用灵活数组时,为什么 memcpy 函数会更改 dst 指针?

问题描述 投票:0回答:1
#include <cstring>
#include <cstdio>
#include <cstdlib>

struct Block {
    int32_t size;
    u_int8_t data[0];
};

int main(int argc, char **argv) {
    Block block;
    Block *ptr = &block;
    u_int8_t data_buffer[] = {1, 3, 0, 1, 3, 4, 5, 5, 6, 2, 2, 3};
    void *sdata = (void *)data_buffer;
    void *ndata = (void*)ptr->data;
    printf("data ptr: %p\n", ptr->data);      // 0x7ffe53275340
    printf("ndata: %p\n", ndata);             // 0x7ffe53275340
    memcpy((void*)ndata, &data_buffer, sizeof(void*));
    printf("ndata: %p\n", ndata);            // 0x505040301000301
    printf("*(&data_buffer): %p\n", *(&data_buffer)); // 0x7ffe53275330
    printf("data ptr: %p\n", ptr->data);     // 0x7ffe53275340
    for(int i{0}; i<12; i++) {
        printf("%d ", (((u_int8_t*)(ptr->data))[i]));
    }
    printf("\n");
    return 0;
}

代码块如上,

我很困惑,在memcpy函数之后,为什么ndata会变成0x505040301000301,一个如此奇怪的值?

我用谷歌搜索了灵活数组,但找不到确切的这种例子。 任何帮助将不胜感激。

c++ c c++11 memcpy flexible-array-member
1个回答
0
投票

具有灵活数组成员的结构体的大小不包括该成员的空间。 因此,如果您在堆栈上声明这样的结构,您实际上无法访问这些元素,因为它们不存在。 你正在做的是未定义的行为,因为你访问的内存超出了对象的边界。

您需要做的是声明一个指向该结构的指针,并为该结构以及所需数量的成员分配空间。

u_int8_t data_buffer[] = {1, 3, 0, 1, 3, 4, 5, 5, 6, 2, 2, 3};
Block *ptr = malloc(sizeof(Block) * sizeof(data_buffer));
© www.soinside.com 2019 - 2024. All rights reserved.