Search code examples
cpointersembeddedatmelstudio

Dereferenced pointer changes address in function call


I have a struct declared and set in memory, I have a global constant pointer to this struct and throughout my program I dereference this pointer to access the different parts of the struct. However, there are times when the pointer memory address changes when dereferenced from a specific function.

My struct

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;

The constant pointer is declared by setting the memory address of the data (externally loaded and outside of the applications memory)

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

To get a notification from the 'notificationConfig' array I dereference 'theConfigData' by [1]:

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

The following occurs when stepping through the code on the uC:

  1. In function A, get notification from struct by using [1], pointer address is 0x463e18
  2. In function A call function B, dereference the struct using [1] the address changes to 0x463e2a (This is the wrong memory address, 0x12 difference)
  3. Function B finishes and returns to A, dereferencing theConfigData again using [1] gives 0x463e18
  4. Every other function in the program that uses [1] always returns the correct (0x463e18) address.

Function B does not alter 'theConfigData' in any way. In the debuggers memory view, the data in 0x0460000 + sizeOf(configData_t) is not altered in any way.

How is the 'pNotificationConfig' pointer changing address when going from function A to B?


Solution

  • You need to make sure that :

    • the definition of configData_t is exactly the same in both the function A and function B compilation units
    • the struct padding of configData_t is exactly the same for both the function A and function B compilation units

    Red flags of the above for your specific issue would be eg. :

    • sizeof(configData_t) is different
    • offsetof(configData_t, notificationConfig) is different
    • sizeof(notificationConfig_t) is different

    If one or more of these red flags are raised (and in a comment, you confirm that), you need to determine which of the two earlier options causes it :

    • a difference in definition can be caught by verifying the source code :
      • make sure the same struct definitions are used throughout the code (typically with the use of an include file)
      • make sure supporting compile time values are the same (eg. array dimensions MAX_INPUT, MAX_OUTPUT, ... in your case)
    • a difference in padding can be caused by the use of different compilers and/or different compiler flags - refer to your compiler's documentation for details (specifically wrt. struct padding/packing)