Home > Blockchain >  How do I get a pointer to the end of my struct?
How do I get a pointer to the end of my struct?

Time:09-17

I have a custom memCopy() function from a TI motorware project. The function takes a start address pointer, an end address pointer and a destination address pointer.

void memCopy(uint16_t *srcStartAddr,uint16_t *srcEndAddr,uint16_t *dstAddr)

I want to use this function to copy a structure from Flash into a copy of that structure in RAM. I'm trying save those addresses as pointers as below.

uint16_t *start;
uint16_t *end; 
uint16_t *dest;

start = (uint16_t *)&myStructInFlash;
end = (uint16_t *)(&myStructInFlash   (sizeof(myStructInFlash)));
dest = (uint16_t *)&myStructInRAM;

When I step the code through in the debugger, the start and dest pointers look correct, but the end pointer is rubbish. Something like 0xFFFFFFFF I think, it didn't make sense to me anyway.

I assume the problem is with my "address arithmetic". Is there a proper way to do this?

Thanks in advance, Colm

Follow up:

Great, thanks Ian. I was not aware that's how pointer arithmetic worked.

As the others have mentioned about the inclusive vs exclusive last address... The function is as follows

void memCopy(uint16_t *srcStartAddr,uint16_t *srcEndAddr,uint16_t *dstAddr)
{

  while(srcStartAddr <= srcEndAddr)
    { 
      *dstAddr   = *srcStartAddr  ;
    }

  return;
}

From this, I think it would require the "last uint16_t" as opposed to the uint16_t that comes after which (&myStruct 1) would produce.

How would I obtain the uint16_t just before that? (uint16_t)((&myStruct 1) - 1) ?

CodePudding user response:

Addition of a pointer and integer is scaled up by the size of the dereferenced type of the pointer. So to find the address just past the end of an object, add 1 to the address produced by the & "address of" operator acting on the object:

  • &myStructInFlash points to the start of myStructInFlash.
  • &myStructInFlash 1 points just past the end of myStructInFlash.

Also, subtraction of two pointers of compatible type is scaled down by the size of the dereferenced type of the pointers, so:

  • The expression (&myStructInFlash 1 - &myStructInFlash) == 1 is true.

If those addresses are converted to char * (or some other narrow character pointer type) then since sizeof(char)==1 is true by definition:

  • (char *)&myStructInFlash points to the first byte of myStructInFlash.
  • (char *)(&myStructInFlash 1) points to the byte just past the end of myStructInFlash.
  • The expression (char *)&myStructInFlash sizeof(myStructInFlash) == (char *)(&myStructInFlash 1) is true.
  • The expression (char *)(&myStructInFlash 1) - (char *)&myStructInFlash == sizeof(myStructInFlash) is true.
uint16_t *start;
uint16_t *end; 
uint16_t *dest;

start = (uint16_t *)&myStructInFlash;
end = (uint16_t *)(&myStructInFlash   1);
dest = (uint16_t *)&myStructInRAM;

Note: For the above code to be correct, &myStructInFlash and &myStructInRAM must be suitably aligned for conversion to uint16_t *, and sizeof(myStructInFlash) must be a multiple of _Alignof(uint16_t). Additionally, memCopy() will no doubt require (char *)end - (char *)start to be a multiple of sizeof(uint16_t).


EDIT: According to the comment from OP, end should actually point to the last uint16_t of the data, not just past the end of the data, so the assignment to end should be:

end = (uint16_t *)(&myStructInFlash   1) - 1;

CodePudding user response:

You could just copy one byte at a time:

uint16_t numBytes = sizeof(myStructInFlash);

for(uint16_t thisByte; thisByte<numBytes; thisByte  )
{
    *((uint8_t*)dstAddr   thisByte) = *((uint8_t*)srcStartAddr   thisByte);
}
  • Related