使用CMSIS-DSP库计算幅值时结构体变量被破坏致程序崩溃的问题
问题分析与解决建议
核心原因:内存越界访问
这种修改无关变量、中途崩溃的情况,90%以上是内存越界导致的,结合你的场景,具体可能的点:
magnitude_output数组空间不足
FFT输出是复数数组,长度为fft_size的话,复数元素有fft_size个,对应幅值数组需要的空间是fft_size个float(每个复数对应一个幅值)。如果给magnitude_output分配的空间小于fft_size,循环写到后面就会溢出,覆盖到其他结构体的内存区域。比如你提到的128点FFT,要是幅值数组只开了40个float的空间,写到第41个时就会越界。fft_output数组范围不对
检查fft_output的实际有效长度:CMSIS-DSP的FFT输出是fft_size个复数(共2*fft_size个float),如果传入的fft_output实际长度不足2*fft_size,循环里fft_output++会读到非法内存,甚至改写其他变量。未声明局部变量
j
你的代码里for循环用了j,但函数内没声明这个变量(只声明了real和imag),这会导致j是个随机的栈变量,循环次数可能远超预期,直接触发内存越界。这是明显的语法漏洞,必须先补上。
快速排查与修复步骤
- 先补全函数的局部变量声明:
void calculate_magnitude(float *fft_output,float *magnitude_output,uint32_t fft_size){ float real,imag; uint32_t j; // 补上这行,避免未定义行为 for( j = 0 ; j < fft_size ; j++ ){ real = *fft_output++; imag = *fft_output++; *magnitude_output++= sqrtf( (real * real) + (imag * imag) ) ; } } - 验证内存分配是否足够:
- 确认
magnitude_output的分配大小:比如128点FFT,需要float magnitude[128];;如果是动态分配,要确保malloc(fft_size * sizeof(float))。 - 确认
fft_output的大小:FFT输入输出都是2*fft_size个float(复数数组),比如128点FFT需要float fft_buf[256];。
- 确认
- 调试时确认内存地址:
在调试器里查看magnitude_output的起始地址和结束地址,再看被破坏的结构体变量的地址,确认是否有重叠。如果重叠,就是幅值数组空间不够。
关于CMSIS-DSP库函数的补充说明
使用arm_cmplx_mag_f32时要严格遵循参数要求:
- 输入
pSrc是复数数组,长度为2*blockSize - 输出
pDst是幅值数组,长度为blockSize - 第三个参数
blockSize就是你的fft_size
如果调用时传错了blockSize(比如传成2*fft_size),也会直接导致输出数组越界,引发和自定义函数一样的问题。
内容的提问来源于stack exchange,提问作者Ho3ein H K
相关产品推荐
相关产品推荐

