C 为什么带有%p指针格式说明符的printf会在AVR上打印垃圾字符而不是地址?

C 为什么带有%p指针格式说明符的printf会在AVR上打印垃圾字符而不是地址?,c,avr,C,Avr,我看到了——得出的结论基本上是: printf()-在嵌入式目标上的调试有点复杂,您需要深入研究并找出是否有将printf()与串行端口连接的代码,等等。另外,一个完整的printf()可能有点重,所以您可能已经在使用一个精简的标准库了。这不是编译器的责任,您需要弄清楚它是如何实现的 。。。但我真的不明白为什么我的问题会发生 我有一个变量,我想用作“字符串数组”,我想将其转换为malloc和realloc: char** my_array = malloc(sizeof(char*)*1);

我看到了——得出的结论基本上是:

printf()-在嵌入式目标上的调试有点复杂,您需要深入研究并找出是否有将printf()与串行端口连接的代码,等等。另外,一个完整的printf()可能有点重,所以您可能已经在使用一个精简的标准库了。这不是编译器的责任,您需要弄清楚它是如何实现的

。。。但我真的不明白为什么我的问题会发生

我有一个变量,我想用作“字符串数组”,我想将其转换为malloc和realloc:

char** my_array = malloc(sizeof(char*)*1);
然后,我将
printf
重定向到“打印”到USB串行端口,然后在串行终端中读取打印输出

据我所知,printf的
%p
格式说明符应该将变量的地址打印为十六进制数。我有这样一句话:

printf("my_array %p\r\n", (void *)&my_array);
my_array  ▒▒▒ꓣ▒▒▒▒/▒▒f'w'▒`$▒▒W*▒▒X▒f'w'▒`$▒▒Y*▒▒Z▒f'w'▒`▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒#▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒j▒{▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒i▒z▒▒`$▒▒
我也试过:

printf("my_array %p\r\n", &my_array);
printf("my_array %p\r\n", my_array);
在所有情况下,我得到的打印输出如下:

printf("my_array %p\r\n", (void *)&my_array);
my_array  ▒▒▒ꓣ▒▒▒▒/▒▒f'w'▒`$▒▒W*▒▒X▒f'w'▒`$▒▒Y*▒▒Z▒f'w'▒`▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒#▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒j▒{▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒i▒z▒▒`$▒▒
。。。很明显,这不是一个十六进制数

为什么会这样,我做错了什么?我怎样才能得到一个在AVR中打印为十六进制数的变量的地址?如果重要的话,我使用CodeVisionAVR编译器


编辑:找到以下内容:

但是人们真的使用了%p吗?尤其是在AVR上。在AVR上,指针是一个16位无符号数。我通常只会自己使用%04X之类的东西

(好的,我刚刚意识到这个论坛可能意味着32位ARM或UC3,我猜指针是32位的?即使如此,在这种情况下是%08X)

。。。所以我用了:

printf("my_array %08X\r\n", (void *)&my_array);
。。。现在我得到了打印输出:

my_array 00003FFB

。。。但是现在我不知道这是否是一个实际地址:)

您可以将指针投射到
uintpttr\t
并打印:

printf("my_array %llu\r\n", (unsigned long long)(uintptr_t)&my_array);

您可以将指针投射到
uintptr\t
并打印:

printf("my_array %llu\r\n", (unsigned long long)(uintptr_t)&my_array);

非常感谢,@dbush-请注意:我使用8/16位微控制器,对于
%llu
/
无符号长
,我不断得到“错误:对于64位整数支持,请使用'math64.h',即使我添加了
\include
。转到
%lu
/
unsigned long
解决了这个问题<代码>uintptr_t需要
#包括
。最后,
%lu
打印一个十进制数,对于hex(),我使用了
0x%08lX
。现在,我得到的是
0x00000014
而不是
0x00003FFB
,不确定它是否描述了一个实际地址-但至少printf问题得到了解决。@sdbbs不确定它是否描述了一个实际地址-你是对的,值
0x14
不能是AVR中的内存地址,因为它位于IO端口tom地址之下(甚至更多-核心寄存器地址范围
0x00
-
0x1F
)。还有一点需要注意的是:我尝试了一些与常规寄存器类似的方法(而不是像在OP中那样的双精度寄存器)
char*mytest
;我最后通过
mytest==NULL
检查它,并通过打印输出得到它确实为NULL;对于这种特殊情况,我应该写
printf(“0x%08lX\r\n”,“无符号长”(uintpttr\u t)mytest)
-没有“adress of”符号;这就是打印实际0x0作为地址的原因(如果我添加了符号AND(如
(unsigned long)(uintpttr__\t)和mytest
),那么我得到的是这个0x14非地址。)最终找到了
%p
产生损坏输出的原因-用于
printf
的CodeVision AVR手册规定:“p”-函数参数是指向位于闪存中以null结尾的字符字符串的指针-因此
%p
与“desktop”C中的含义不同,它以十六进制打印指针(这就是为什么我在OP示例中也打印字母的原因)@sdbbs请发布此消息作为对此问题的回答非常感谢,@dbush-仅作几点说明:我使用8/16位微控制器,对于
%llu
/
无符号长
,我不断收到“错误:对于64位整数支持,请使用'math64.h'”,即使我添加了
#include
%lu
/
无符号长
也解决了这个问题。
uintptpr\t
需要
#include
。最后,
%lu
打印一个十进制数,表示十六进制()我最终使用了
0x%08lX
。现在,我得到的是
0x00000014
而不是
0x00003FFB
,还不确定它是否描述了一个实际地址,但至少printf问题得到了解决。@sdbbs还不确定它是否描述了一个实际地址-你是对的,值
0x14
不能是AVR中的内存地址,因为它是located低于IO端口tom地址(甚至更多-核心寄存器地址范围
0x00
-
0x1F
)。只需再注意一点:我尝试了与常规(而不是双精度,如OP)类似的方法
char*mytest
;我最后通过
mytest==NULL
检查它,并通过打印输出得到它确实为NULL;对于这种特殊情况,我应该写
printf(“0x%08lX\r\n”,“无符号长”(uintpttr\u t)mytest)
-没有“adress of”符号;这就是打印实际0x0作为地址的原因(如果我添加了符号AND(如
(unsigned long)(uintpttr__\t)和mytest
),那么我得到的是这个0x14非地址。)最终找到了
%p
产生损坏输出的原因-用于
printf
的CodeVision AVR手册规定:“p”-函数参数是指向位于闪存中以null结尾的字符字符串的指针-因此
%p
与“desktop”C中的含义不同,在“desktop”C中,它以十六进制打印指针(这就是为什么我在OP示例中也打印了字母)@sdbbs请将此作为此问题的答案发布