取消引用全局结构成员的本地引用与 Memcpy’ing

问题描述 投票:0回答:1

我有一个由调用者函数调用的被调用者函数,该函数修改联合中字段成员的内容。该联合嵌套在一个支柱内,并且该结构具有全局作用域。但是,对该特定字段的引用在语法上很长,因此我在调用者函数中声明了一个指向该字段的本地指针,以减少函数调用的冗长性。联合体封装在结构体中,结构体本身的结构如下:

typedef union
{
    uint8_t data[8];
    struct 
    {
        uint32_t data_u32;
    } PARAM_U32;

    struct
    {
        float data_f;
    } PARAM_FLOAT;

 } EXAMPLE_UNION;

typedef struct
{
    EXAMPLE_UNION member1;
    EXAMPLE_UNION member2;
} EXAMPLE_STRUCT;

EXAMPLE_STRUCT global_example_struct;

void callee_func(uint32_t *pDataToModify, uint32_t newVal)
{
    *pDataToModify = newVal;
}

void caller_func()
{

    uint32_t *pMemberOfNestedUnionToModify = (uint32_t *)&EXAMPLE_STRUCT.member1.PARAM_U32.data_u32

    uint32_t dummyNewVal = 0xFFFFFFFF;
    
    callee_func(pMemberOfNestedUnionToModify, dummyNewVal);
}

当 callee_func() 直接尝试取消引用作为参数传入的指针时,会发生硬错误。这让我很困惑,因为虽然它是本地引用,但它引用了全局范围的数据。然而,当 callee_func() 仅将内存复制到指针时,操作成功并且字段被更新:

void callee_func(uint32_t *pDataToModify, uint32_t newVal)
{
    // this works
    memcpy((uint8_t *)pDataToModify, (uint8_t *)&newVal, 4);
}

为什么取消引用参数中传递的本地指针是无效的,但向其复制数据却是有效的?是否因为本地引用只是一个引用,仅指向全局范围数据的实例,因此没有分配堆栈空间来实际存储值?

c memcpy dereference
1个回答
0
投票

您遇到的问题是由于您在

caller_func()
中引用全局结构实例的方式造成的。具体来说,您使用的是类型名称
EXAMPLE_STRUCT
而不是实际实例
global_example_struct

在您的代码中,您有:

uint32_t *pMemberOfNestedUnionToModify = (uint32_t *)&EXAMPLE_STRUCT.member1.PARAM_U32.data_u32;

这里,

EXAMPLE_STRUCT
指的是类型,而不是变量。尝试获取类型成员的地址是无效的,并会导致未定义的行为,在您的情况下,这会在取消引用时导致硬故障。

您应该引用全局实例

global_example_struct
而不是类型名称。这是更正后的行:

uint32_t *pMemberOfNestedUnionToModify = &global_example_struct.member1.PARAM_U32.data_u32;

通过此更改,您可以正确获取全局结构实例中

data_u32
的地址,并且在
callee_func()
中取消引用此指针应该可以正常工作,而不会导致硬故障。

© www.soinside.com 2019 - 2024. All rights reserved.