函数间传递RTC生成的文件名字符串出现数据丢失问题求助
字符串传递后截断的问题分析与修复方案
问题根源
- 未初始化的数组引发内存越界
file1.c里的char dateAndTimeFile[];只声明了数组却没指定大小,也没分配足够内存存拼接后的文件名。sprintf写入时会超出数组边界,破坏内存结构,后续访问字符串自然会出现截断或乱码。 - 字符类型强制转换导致解析错误
代码里把char*强转成TCHAR*,如果编译环境是Unicode模式(定义了_UNICODE宏),TCHAR等价于wchar_t,这种直接转换会让字符串解析出错,只能读到第一个字节对应的宽字符,表现为字符串截断。 - 指针指向的内存可能失效
如果dateAndTimeFile是局部变量,函数执行完后内存会被释放,inputfile就变成野指针,访问时会出现不可预料的错误。
修复方案
方案1:固定数组大小,统一字符类型
修改file1.c:
// 计算文件名最大长度:HealthFile20 + 6组两位时间 + LOG.txt + 终止符,预留足够空间 char dateAndTimeFile[32]; void setUserDefinedTime(int rtc_year, int rtc_month, int rtc_day, int rtc_hour, int rtc_minute, int rtc_second){ // 用_snprintf避免缓冲区溢出 _snprintf(dateAndTimeFile, sizeof(dateAndTimeFile), "HealthFile20%02d%02d%02d%02d%02d%02dLOG.txt", rtc_year, rtc_month, rtc_day, rtc_hour, rtc_minute, rtc_second); // 手动添加终止符,确保字符串合法 dateAndTimeFile[sizeof(dateAndTimeFile)-1] = '\0'; setParameterCreateInputFile(dateAndTimeFile); }
修改file2.c,避免直接赋值指针,改用内存复制:
char *inputfile = NULL; void setParameterCreateInputFile(char str[]){ // 先释放旧内存(如果之前分配过) if(inputfile != NULL){ free(inputfile); } // 分配足够内存并复制字符串 inputfile = malloc(strlen(str)+1); if(inputfile != NULL){ strcpy(inputfile, str); } printf("file:%s\n", inputfile); SDCARD_Open(); } void SDCARD_Open(void){ if(inputfile != NULL){ printf("LOAD %s\n", inputfile); } // 使用完毕释放内存,避免泄漏 free(inputfile); inputfile = NULL; }
方案2:统一使用TCHAR适配Unicode环境
如果项目要求用Unicode编码,全量替换为TCHAR相关函数:
file1.c:
TCHAR dateAndTimeFile[32]; void setUserDefinedTime(int rtc_year, int rtc_month, int rtc_day, int rtc_hour, int rtc_minute, int rtc_second){ _sntprintf(dateAndTimeFile, sizeof(dateAndTimeFile)/sizeof(TCHAR), _T("HealthFile20%02d%02d%02d%02d%02d%02dLOG.txt"), rtc_year, rtc_month, rtc_day, rtc_hour, rtc_minute, rtc_second); dateAndTimeFile[sizeof(dateAndTimeFile)/sizeof(TCHAR)-1] = _T('\0'); setParameterCreateInputFile(dateAndTimeFile); }
file2.c:
TCHAR *inputfile = NULL; void setParameterCreateInputFile(TCHAR str[]){ if(inputfile != NULL){ free(inputfile); } inputfile = malloc((_tcslen(str)+1)*sizeof(TCHAR)); if(inputfile != NULL){ _tcscpy(inputfile, str); } _tprintf(_T("file:%s\n"), inputfile); SDCARD_Open(); } void SDCARD_Open(void){ if(inputfile != NULL){ _tprintf(_T("LOAD %s\n"), inputfile); } free(inputfile); inputfile = NULL; }
关键注意事项
- 永远不要用未指定大小的字符数组存格式化后的字符串,必须提前算好所需空间,或用动态内存分配。
- 避免
char和TCHAR之间的强制转换,统一项目的字符编码模式。 - 用指针存储外部字符串时,不要直接赋值指针(除非能确定原内存一直有效),最好复制到自己管理的内存中,避免野指针问题。
内容的提问来源于stack exchange,提问作者Armando Ferreira
相关产品推荐
相关产品推荐

