C IAR微控制器中的sprintf腐蚀阵列

C IAR微控制器中的sprintf腐蚀阵列,c,embedded,microcontroller,printf,C,Embedded,Microcontroller,Printf,我目前正在学习嵌入式编程,因此正在使用带有ARM架构的TI微控制器的IAR平台上工作。由于我对此类编程或一般的C编程的技术细节一无所知,我想问一个基本问题: 我有以下简单的代码片段: int i; for(i = 0; i < NUM_SAMPLES; i++) { sinTable[i] = sinf(2*i*dT*PI); } for(i = 0; i < NUM_SAMPLES; i++) { char out[32]; sprintf(out,"s

我目前正在学习嵌入式编程,因此正在使用带有ARM架构的TI微控制器的IAR平台上工作。由于我对此类编程或一般的C编程的技术细节一无所知,我想问一个基本问题:

我有以下简单的代码片段:

int i;
for(i = 0; i < NUM_SAMPLES; i++)
{
    sinTable[i] = sinf(2*i*dT*PI);
}


for(i = 0; i < NUM_SAMPLES; i++)
{
    char out[32];
    sprintf(out,"sin: %.7f, %.7f;", i*dT, sinTable[i]);
    putString(out);
    delay(DELAY_100US);
}
inti;
对于(i=0;i
其中,
sinTable[]
是大小为
NUM_SAMPLES
的全局变量,
putString(*char)
是一个写入RS232端口的函数,
delay(float)
是一个简单的延迟函数

我的问题是,一旦调用
sprintf(…)
,它就会破坏
sinTable
,在COM信号的接收端绘制表格时会产生一些非常奇怪的结果

我不希望内存耗尽,因为MC有64KB的SRAM


有人有什么想法吗?

您似乎非常确信结果字符串只有31个字符长。使用sprintf语句损坏另一个变量的唯一方法是结果字符串长度超过32字节(31个字符和一个nul字节),因此会覆盖内存的其他部分。使数字变小或使临时缓冲区变大。

当到达
main
时,确保堆栈指针位于64位边界上


您看到的症状是典型的堆栈在奇数32位边界上对齐。在将double用作variadac参数之前,一切似乎都正常工作。当代码期望此类参数在8字节边界上时,这种情况就会中断。

感谢所有对此问题提出解决方案的人。我最终编写了一个转换方法,该方法给出了字符串的十六进制表示形式,并将其传输,完全省略了
sprintf(…)

它非常粗糙,但适合我的需要。

进一步检查后: 我怀疑Michael Burr关于堆栈利用率的回应是正确的。选择一个较小的printf库可能就足够了,但如果您可以增加堆栈大小,这似乎更安全。请注意,《IAR C/C++开发指南》包含链接器堆栈使用分析的信息

原件: 当我从IAR 6.1(许可)升级到6.4(kickstart)时,我遇到了一个类似的问题——vsnprintf写入“整个RAM”,尽管返回值表明写入的字符数在目标范围内。“解决方案”是避免使用支持多字节的printf库

项目选项>常规>库选项>打印不带多字节的小文件

可能还想取消选中

项目选项>C/C++编译器/语言2/启用多字节

我试图向IAR报告此事,但由于我的支持合同到期


不幸的是,IAR 7.3.4又出现了类似的问题,多字节“修复”似乎还不够。sprintf()和snprintf()都会发生这种情况,尽管这两种情况下的越界损坏不完全相同。

采样数有多高,
dT
的值是多少?
sprintf
不会损坏sinTable,除非它已经损坏。我要研究两件事:1)IAR的运行时有关于
printf()
函数系列支持级别的选项。我认为默认情况下通常不启用浮点支持—请确保已启用它;2) 函数的
printf()
系列使用了相当多的堆栈空间。确保分配给任务的堆栈足够大。@汤姆:尝试将
char out[32]
更改为
char out[200]
。还可以尝试将
字符输出[32]
更改为
静态字符输出[32]
,并告诉我们这是否会改变任何内容。这不是一个真正的解决方案,但结果可能会给我们一些线索。除非有中断例程覆盖背景上的随机内存位置,否则它闻起来像某种溢出。您没有收到任何编译器警告?您可以尝试启用备注(编译器和链接器),以查看编译器是否看到任何可疑的内容。还可以启用链接器映射创建,并查看是否有任何靠近
sinTable
的内容可能在那里溢出。使用调试器,我发现内存区域没有重叠。假设它仍然显示,并且没有显示在调试器中,当选择字长256时,结果仍然相同。