C语言无法为动态分配的二维数组元素赋值问题排查
问题排查结论
你的代码一共三个问题,第一个直接导致输出全0:
1. 打印函数格式符用错(核心原因)
simpMat_Print里你拿%d打印float类型元素:
printf("%d ", Matrix->elements[i][j]);
%d是输出整数的格式符,float传入可变参数函数会自动提升为double,类型和格式符不匹配属于未定义行为,最后输出结果全为0。
直接把%d改成%f即可,要控制小数位数可以写类似%.1f的格式。
2. C/C++混编没做符号兼容
你编译的时候把纯C写的库文件命名为.cpp用g编译,g会对函数名做C++的名字修饰,但是你的测试文件是C代码,会按照C的规则查找未修饰的函数符号,你没加兼容声明的话,哪怕侥幸链接出可执行文件,调用逻辑也可能异常,部分环境下会直接链接报错。
两个修复方案选一个即可:
- 把
simpMat.cpp改名成simpMat.c,编译库的时候用gcc -c simpMat.c,纯C代码全程用C编译器编译最稳妥 - 要保留.cpp后缀的话,就在头文件的函数声明外面包一层C++兼容的
extern "C"块:
#ifdef __cplusplus extern "C" { #endif // 所有函数声明放在这里 void simpMat_Init(simpMat *Matrix, uint8_t nRows, uint8_t nColumns, uint8_t nElements, float elements[]); void simpMat_Print(simpMat *Matrix); void simpMat_Delete(simpMat *Matrix); #ifdef __cplusplus } #endif
3. 参数传错存在越界风险
你测试代码里的toAppend数组只有6个元素,3行2列的矩阵本来也只需要6个元素,但你给nElements传了9。现在Init函数虽然没用到nElements做循环计数不会立刻出问题,但如果后续加参数校验或者修改循环逻辑,就会读取数组外的非法内存值。
把传参改成simpMat_Init(&Matrix1, 3, 2, 6, toAppend);即可,后续最好在Init函数里加校验,如果nElements不等于行数乘列数直接返回错误。
改完格式符之后重新编译,运行就能得到正确结果:
MATRIX ELEMENTS ARE: 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000
额外提一句:纯C环境下malloc的返回值不需要强转成float**/float*,C语言里void*可以隐式转成任意指针类型,多余的强转反而可能掩盖漏引入stdlib.h的问题,不过这个不影响当前运行。
内容的提问来源于stack exchange,提问作者kucar
相关产品推荐
相关产品推荐

