下面的代码是一个示例,地址是指微控制器的闪存,因此它不会指向任何垃圾数据。
我要做的是将指针“end_adress”指向内存块的末尾。在这种情况下,块的开始是0x00001000,块的结尾是0x00002000。我想通过使用起始地址和内存块大小的知识来设置“end_adress”变量。
这是解决问题的好方法吗? 好的是可读代码,欢迎任何其他建议!
static const uint32_t memory_size = 0x00001000;
static volatile const uint32_t* start_address = (volatile const uint32_t*)0x00001000;
static volatile uint32_t* end_address;
int main(int argc, char *argv[])
{
end_address = start_address + (memory_size/sizeof(end_address));
printf("End adress: %x \n", end_address);
return 0;
}
答案 0 :(得分:3)
要解决您的问题,请替换此
end_address = start_address + (memory_size/sizeof(end_address));
使用:
end_address = start_address + (memory_size/sizeof(*end_address));
原因:end_address
本身是指针,而*end_address
实际上是指针指向的数据类型。 sizeof(uint32_t) != sizeof(char*)
例如char*
会导致问题。在64位或16位系统上。
然而,当您使用内存地址时,我建议您使用类型为char *memory_size = 0x00001000;
uint32_t memory_size = 0x1000;
char *end_address = memory_size + memory_size;
/* then it's assured that end_address == 0x00002000 */
的指针,以便您可以使用它进行直接算术:
{{1}}
答案 1 :(得分:1)
你的方式几乎没问题(*end_address
除外),如另一个答案所述。但是, 仍然是一个问题。
您的memory_size
为字节,而sizeof
则为 char
的倍数。 sizeof(char)
总是一个,但char可能不一定是一个字节(一个例子是我正在编码的TI芯片,其中char
有两个字节。)
让我们看看在这种情况下会发生什么:
/* char is two bytes */
/* sizeof(char) == 1 */
/* sizeof(uint32_t) == 2 */
end_address = start_address + (memory_size/sizeof *end_address);
转换为:
end_address = (uint32_t *)0x1000 + (0x1000 / 2);
转换为:
end_address = (uint32_t *)0x1000 + 0x800;
表示0x1000后的0x800 * 4字节,即0x3000(不是0x2000)。
你应该做些什么来确保使用CHAR_BIT
(来自limits.h
)来说明一个字符有多少字节。然后做:
end_address = start_address + memory_size / sizeof *end_address / (CHAR_BIT / 8);
假设CHAR_BIT
是8的倍数。如果不是,你必须知道一个字节中的位数是多少,除以它!
请注意,我/ (CHAR_BIT / 8)
(而不是* 8 / CHAR_BIT
)以防止任何可能的溢出。
或者,你可以写:
end_address = (void *)((char *)start_address + memory_size / (CHAR_BIT / 8));
根据您习惯的方式,它可能看起来更清晰或更混乱,但在其他方面是相同的。