如何获得指向结构末尾的指针?
How do I get a pointer to the end of my struct?
我有一个来自 TI motorware 项目的自定义 memCopy() 函数。
该函数采用起始地址指针、结束地址指针和目标地址指针。
void memCopy(uint16_t *srcStartAddr,uint16_t *srcEndAddr,uint16_t *dstAddr)
我想使用此功能将一个结构从闪存复制到 RAM 中该结构的副本。
我正在尝试将这些地址保存为如下指针。
uint16_t *start;
uint16_t *end;
uint16_t *dest;
start = (uint16_t *)&myStructInFlash;
end = (uint16_t *)(&myStructInFlash + (sizeof(myStructInFlash)));
dest = (uint16_t *)&myStructInRAM;
当我在调试器中逐步执行代码时,开始和目标指针看起来是正确的,但结束指针是垃圾。我认为像 0xFFFFFFFF 这样的东西,反正对我来说没有意义。
我认为问题出在我的“地址算法”上。
有没有正确的方法来做到这一点?
提前致谢,
科尔姆
跟进:
太好了,谢谢伊恩。我不知道指针算法是这样工作的。
正如其他人提到的关于包容性与独占最后地址...功能如下
void memCopy(uint16_t *srcStartAddr,uint16_t *srcEndAddr,uint16_t *dstAddr)
{
while(srcStartAddr <= srcEndAddr)
{
*dstAddr++ = *srcStartAddr++;
}
return;
}
据此,我认为它需要“最后一个 uint16_t”,而不是 (&myStruct + 1) 之后产生的 uint16_t。
在那之前我如何获得 uint16_t? (uint16_t)((&myStruct + 1) - 1) ?
指针和整数的相加按指针的取消引用类型的大小放大。因此,要找到刚好超过对象末尾的地址,请将 1 添加到由作用于对象的 &
“地址”运算符产生的地址:
&myStructInFlash
指向myStructInFlash
的开始。
&myStructInFlash + 1
点刚好超过 myStructInFlash
. 的结尾
此外,两个兼容类型指针的减法按指针的取消引用类型的大小缩小,因此:
- 表达式
(&myStructInFlash + 1 - &myStructInFlash) == 1
为真。
如果这些地址被转换为 char *
(或其他一些窄字符指针类型),那么根据定义 sizeof(char)==1
为真:
(char *)&myStructInFlash
指向myStructInFlash
的第一个字节。
(char *)(&myStructInFlash + 1)
指向刚好超过 myStructInFlash
末尾的字节。
- 表达式
(char *)&myStructInFlash + sizeof(myStructInFlash) == (char *)(&myStructInFlash + 1)
为真。
- 表达式
(char *)(&myStructInFlash + 1) - (char *)&myStructInFlash == sizeof(myStructInFlash)
为真。
uint16_t *start;
uint16_t *end;
uint16_t *dest;
start = (uint16_t *)&myStructInFlash;
end = (uint16_t *)(&myStructInFlash + 1);
dest = (uint16_t *)&myStructInRAM;
注意:为使上述代码正确,&myStructInFlash
和 &myStructInRAM
必须适当对齐以转换为 uint16_t *
,并且 sizeof(myStructInFlash)
必须是以下的倍数_Alignof(uint16_t)
。此外,memCopy()
无疑要求 (char *)end - (char *)start
是 sizeof(uint16_t)
.
的倍数
EDIT:根据 OP 的评论,end
实际上应该指向数据的最后一个 uint16_t
,而不仅仅是指向数据的末尾数据,所以分配给 end
应该是:
end = (uint16_t *)(&myStructInFlash + 1) - 1;
您可以一次只复制一个字节:
uint16_t numBytes = sizeof(myStructInFlash);
for(uint16_t thisByte; thisByte<numBytes; thisByte++)
{
*((uint8_t*)dstAddr + thisByte) = *((uint8_t*)srcStartAddr + thisByte);
}
我有一个来自 TI motorware 项目的自定义 memCopy() 函数。 该函数采用起始地址指针、结束地址指针和目标地址指针。
void memCopy(uint16_t *srcStartAddr,uint16_t *srcEndAddr,uint16_t *dstAddr)
我想使用此功能将一个结构从闪存复制到 RAM 中该结构的副本。 我正在尝试将这些地址保存为如下指针。
uint16_t *start;
uint16_t *end;
uint16_t *dest;
start = (uint16_t *)&myStructInFlash;
end = (uint16_t *)(&myStructInFlash + (sizeof(myStructInFlash)));
dest = (uint16_t *)&myStructInRAM;
当我在调试器中逐步执行代码时,开始和目标指针看起来是正确的,但结束指针是垃圾。我认为像 0xFFFFFFFF 这样的东西,反正对我来说没有意义。
我认为问题出在我的“地址算法”上。 有没有正确的方法来做到这一点?
提前致谢, 科尔姆
跟进:
太好了,谢谢伊恩。我不知道指针算法是这样工作的。
正如其他人提到的关于包容性与独占最后地址...功能如下
void memCopy(uint16_t *srcStartAddr,uint16_t *srcEndAddr,uint16_t *dstAddr)
{
while(srcStartAddr <= srcEndAddr)
{
*dstAddr++ = *srcStartAddr++;
}
return;
}
据此,我认为它需要“最后一个 uint16_t”,而不是 (&myStruct + 1) 之后产生的 uint16_t。
在那之前我如何获得 uint16_t? (uint16_t)((&myStruct + 1) - 1) ?
指针和整数的相加按指针的取消引用类型的大小放大。因此,要找到刚好超过对象末尾的地址,请将 1 添加到由作用于对象的 &
“地址”运算符产生的地址:
&myStructInFlash
指向myStructInFlash
的开始。&myStructInFlash + 1
点刚好超过myStructInFlash
. 的结尾
此外,两个兼容类型指针的减法按指针的取消引用类型的大小缩小,因此:
- 表达式
(&myStructInFlash + 1 - &myStructInFlash) == 1
为真。
如果这些地址被转换为 char *
(或其他一些窄字符指针类型),那么根据定义 sizeof(char)==1
为真:
(char *)&myStructInFlash
指向myStructInFlash
的第一个字节。(char *)(&myStructInFlash + 1)
指向刚好超过myStructInFlash
末尾的字节。- 表达式
(char *)&myStructInFlash + sizeof(myStructInFlash) == (char *)(&myStructInFlash + 1)
为真。 - 表达式
(char *)(&myStructInFlash + 1) - (char *)&myStructInFlash == sizeof(myStructInFlash)
为真。
uint16_t *start;
uint16_t *end;
uint16_t *dest;
start = (uint16_t *)&myStructInFlash;
end = (uint16_t *)(&myStructInFlash + 1);
dest = (uint16_t *)&myStructInRAM;
注意:为使上述代码正确,&myStructInFlash
和 &myStructInRAM
必须适当对齐以转换为 uint16_t *
,并且 sizeof(myStructInFlash)
必须是以下的倍数_Alignof(uint16_t)
。此外,memCopy()
无疑要求 (char *)end - (char *)start
是 sizeof(uint16_t)
.
EDIT:根据 OP 的评论,end
实际上应该指向数据的最后一个 uint16_t
,而不仅仅是指向数据的末尾数据,所以分配给 end
应该是:
end = (uint16_t *)(&myStructInFlash + 1) - 1;
您可以一次只复制一个字节:
uint16_t numBytes = sizeof(myStructInFlash);
for(uint16_t thisByte; thisByte<numBytes; thisByte++)
{
*((uint8_t*)dstAddr + thisByte) = *((uint8_t*)srcStartAddr + thisByte);
}