字符串使用前经常使用自定义的AllTrim(char*)函数去除前后冗余空格,贪图方便使用AllTrim(" QRC ");时触发访问未知内存问题,记录如下。
目录
-
问题背景
-
问题原因
-
解决办法
问题背景
外层函数贪图方便直接传递双引号形式的字符串比如"QRC",内部在实际进行业务处理时习惯性的使用了AllTrim(pInstType);对它进行了处理,结果程序卡住,过几秒后自动退出。
-
#include <stdio.h> #include <string.h> int DisplayString(char *pInstType); void AllTrim(char *str); int main() { int iRet = 0; DisplayString("QRC"); return 0; } int DisplayString(char *pInstType) { AllTrim(pInstType); printf("Info[%s], size[%d], len[%d]\n", pInstType, sizeof(pInstType), strlen(pInstType)); return 0; } void AllTrim(char *str) { int i, j, k, h; for (i=0; str[i]==' ' && str[i]!='\0'; i++) ; for (j=strlen(str)-1; str[j]==' ' && j>=0; j--) ; for (k=0; k<=j-1; k++) { str[k] = str[k+i]; } str[k] = '\0'; while (str[k] != 0) { printf("[LOG_INFO]k=[%d]\n", k); str[k] = 0; k++; } }
程序运行异常,要么一直卡住,要么几秒后终止退出。
问题原因
void AllTrim(char *str)
{
int i, j, k, h;
for (i=0; str[i]==' ' && str[i]!='\0'; i++)
;
printf("[LOG_INFO]i=[%d]\n", i);
for (j=strlen(str)-1; str[j]==' ' && j>=0; j--)
;
printf("[LOG_INFO]str[1]=[%c]\n", str[1]);
for (k=0; k<=j-i; k++)
{
printf("[LOG_INFO]j-1=[%d], i=[%d], k=[%d]\n", j-1, i, k);
printf("[LOG_INFO]str[k]=[%c], str[k+i]=[%c]\n", str[k], str[k+i]);
str[k] = str[k+i]; //问题发生位置
}
printf("[LOG_INFO]str[k]=[%c]\n", str[k]);
str[k] = '\0';
while (str[k] != 0)
{
printf("[LOG_INFO]k=[%d]\n", k);
str[k] = 0;
k++;
}
}
添加打印,重新执行程序:
发现问题发生在给字符串赋值的地方。
双引号传进来的字符串不像这样正规定义的字符串变量有自己的存储地址,没有实际合法地址存储,没有申请内存,就直接赋值,导致赋值存储的位置不可知,访问的位置非法的话就可能导致程序异常。
char sInstType[4];
memcpy(sInstType, 0x00, sizeof(sInstType));
memcpy(sInstType, "QRC", sizeof(sInstType)-1);
解决办法
方案1:双引号传进去的值不使用AllTrim()进行去除空格处理。
方案2:不要偷懒,按步骤申请一个字符数组来存储。