取消引用的指针会更改函数调用中的地址

时间:2018-11-19 09:39:17

标签: c pointers embedded atmelstudio

我在内存中声明并设置了一个结构,我有一个指向该结构的全局常量指针,在我的程序中,我都取消引用了该指针以访问该结构的不同部分。但是,有时从特定功能取消引用后指针存储器地址会发生变化。

我的结构

typedef struct configData_t
{
    uint8_t version[4];
    inputConfig_t  inputModuleConfig  [MAX_INPUT];
    outputConfig_t outputModuleConfig [MAX_OUTPUT];
    notificationConfig_t notificationConfig [MAX_NOTIFICATIONS];
    functionConfig_t autoFunctionConfig [MAX_FUNCTIONS];
    uint16_t Crc16;
} configData_t;

通过设置数据的内存地址(外部加载和应用程序内存之外)来声明常量指针

//Pointer points to memory location on uC (data already in memory)
const configData_t* theConfigData = (configData_t*)0x0460000;

要从'notificationConfig'数组中获取通知,请通过[1]取消引用'theConfigData':

const notificationConfig_t *pNotificationConfig = theConfigData->notificationConfig + notificationID;

单步执行uC上的代码时,会发生以下情况:

  1. 在函数A中,使用[1]从结构获取通知,指针地址为0x463e18
  2. 在函数A调用函数B中,使用[1]取消引用结构,地址更改为0x463e2a(这是错误的内存地址,相差0x12)
  3. 函数B完成并返回到A,再次使用[1]取消引用ConfigData会得到0x463e18
  4. 程序中使用[1]的所有其他函数总是返回正确的(0x463e18)地址。

函数B不会以任何方式更改'theConfigData'。在调试器内存视图中,以任何方式都不会更改0x0460000 + sizeOf(configData_t)中的数据。

从函数A到B时'pNotificationConfig'指针如何更改地址?

1 个答案:

答案 0 :(得分:1)

您需要确保:

  • 在功能A和功能B编译单元中configData_t的定义完全相同
  • 对于函数A和函数B编译单元,configData_t的{​​{3}}完全相同

针对您的特定问题的上述红色标记将是例如。 :

  • sizeof(configData_t)不同
  • offsetof(configData_t, notificationConfig)不同
  • sizeof(notificationConfig_t)不同

如果这些红色标记中的一个或多个被引发(并在注释中确认),则需要确定两个较早选项中的哪个导致它:

  • 通过验证源代码可以发现定义上的差异:
    • 确保在整个代码中使用相同的结构定义(通常使用include文件)
    • 确保支持的编译时间值相同(例如,数组尺寸MAX_INPUTMAX_OUTPUT,根据您的情况……)
  • 使用不同的编译器和/或使用不同的编译器标志可能会导致填充差异-请参阅您的编译器文档以获取详细信息(特别是wrt。struct padding / packing)