C++中uint8_t数组转char数组适配MISRA规则:修复指针算术违规
修复MISRA规则567 S:指针算术未基于数组的问题
问题背景
需要在C++中实现uint8_t数组读取并转换为char数组,且符合MISRA规范。现有代码功能正常,但第24行的arr++触发了MISRA规则567 S(指针算术未基于数组),需修复该问题。
原代码如下:
#include <iostream> using namespace std; int PartNum_Read(char* arr); int PartNum_Read(char* arr) { uint32_t ret = 0U; uint8_t ReadPartNumer[3]={'a','b','c'}; //copy from other function, type is uint8_t if(arr != NULL) { for(int j = 0U; j < sizeof(ReadPartNumer); j++) { *arr = static_cast<char>(ReadPartNumer[j]); arr++; } ret = (sizeof(ReadPartNumer)); } cout << "PN: " << *arr << endl; return ret; } int main() { cout<<"Hello World "; char PartNumer[3]={0}; PartNum_Read(&PartNumer[0]); for(int i = 0U; i < 3; i++) { cout << "PN: " << PartNumer[i] << endl; } return 0; }
修复方案
MISRA规则567 S禁止对未明确关联到数组的指针进行算术操作,核心是避免指针越界或脱离数组范围的风险。以下两种方案均可修复:
方案1:使用数组索引替代指针自增
不修改传入的arr指针,利用循环变量j作为索引定位目标位置,完全规避指针算术操作:
#include <iostream> using namespace std; int PartNum_Read(char* arr); int PartNum_Read(char* arr) { uint32_t ret = 0U; const uint8_t ReadPartNumer[3] = {'a','b','c'}; // 加const符合MISRA只读变量规范 const size_t arr_len = sizeof(ReadPartNumer) / sizeof(ReadPartNumer[0]); if(arr != nullptr) // MISRA C++推荐用nullptr替代NULL { for(size_t j = 0U; j < arr_len; j++) { arr[j] = static_cast<char>(ReadPartNumer[j]); // 通过索引访问目标位置 } ret = arr_len; } // 原代码中*arr已超出传入数组范围,建议移除该输出避免越界 // cout << "PN: " << *arr << endl; return static_cast<int>(ret); } int main() { cout << "Hello World" << endl; char PartNumer[3] = {0}; PartNum_Read(PartNumer); // 直接传数组名,等价于&PartNumer[0],更直观 for(size_t i = 0U; i < 3; i++) { cout << "PN: " << PartNumer[i] << endl; } return 0; }
方案2:使用指针副本进行算术操作
若需保留指针操作逻辑,可创建指针副本执行自增,原指针始终指向数组起始位置,确保算术操作基于明确的数组范围:
#include <iostream> using namespace std; int PartNum_Read(char* arr); int PartNum_Read(char* arr) { uint32_t ret = 0U; const uint8_t ReadPartNumer[3] = {'a','b','c'}; const size_t arr_len = sizeof(ReadPartNumer) / sizeof(ReadPartNumer[0]); if(arr != nullptr) { char* temp_arr = arr; // 创建指针副本 for(size_t j = 0U; j < arr_len; j++) { *temp_arr = static_cast<char>(ReadPartNumer[j]); temp_arr++; // 仅对副本执行自增操作 } ret = arr_len; } // 移除越界访问的输出语句 // cout << "PN: " << *arr << endl; return static_cast<int>(ret); } int main() { cout << "Hello World" << endl; char PartNumer[3] = {0}; PartNum_Read(PartNumer); for(size_t i = 0U; i < 3; i++) { cout << "PN: " << PartNumer[i] << endl; } return 0; }
额外MISRA合规优化点
- 给只读的
ReadPartNumer数组添加const修饰,符合MISRA对常量的规范 - 用
nullptr替代NULL,这是MISRA C++的推荐写法 - 采用
size_t作为循环变量类型,匹配数组长度的类型,避免类型不匹配 - 移除原代码中访问数组越界的
cout << *arr语句,规避未定义行为
内容的提问来源于stack exchange,提问作者Nick Lee
相关产品推荐
相关产品推荐

