该程序采用一个指向 char 数组和 int 的指针。 char 数组由两个数字组成,并用空格分隔。
该函数的用途是将 char 数组的值读取为 int 并将其替换为输入的相乘值:
void read_and_mul(char * arr,int scale) {
int num_arr[2]; // saving values in a int[]
char * ch = strtok(arr," ");
num_arr[0] = scale * (atoi(ch));
ch = strtok(NULL," ");
num_arr[1] = scale * (atoi(ch));
memset(arr,0,sizeof(arr)); // deleting the previous value of the char[]
char one[sizeof (int)];
char two[sizeof (int)];
sprintf(one,"%d",num_arr[0]); // saving the altered numbers as chars
sprintf(two,"%d",num_arr[1]);
strcat(arr,one); // writing the multiplied values to the string
strcat(arr, " ");
strcat(arr,two);
}
但是我这样使用它,它按预期工作,但会导致堆栈崩溃:
int main(int argc, char *argv[]) {
char str[] = "1 2";
read_and_mul((char *) &str, 10);
printf("string after call: %s\n",str);
return 0;
}
CLion 中的终端消息是:
*** stack smashing detected ***: terminated
string after call: 10 20
这是一个潜在的错误还是 IDE 警告以及导致它的原因是什么?
该函数必须构建包含 6 个字符的字符串
"10 20"
,其中包括终止空字符 '\0'
。
但是您正在尝试将此字符串存储在仅包含
4
字符 的数组中
char str[] = "1 2";
由于这些陈述
strcat(arr,one); // writing the multiplied values to the string
strcat(arr, " ");
strcat(arr,two);
因此该函数已经调用了未定义的行为。
另一个问题是在这个
memset
的调用中
memset(arr,0,sizeof(arr));
变量
arr
具有指针类型char *
。如果 sizeof( char * )
等于 8
则再次尝试写入数组外部的内存。
要解决此问题,您应该在函数内动态分配一个新的字符数组,其中将存储结果字符串,并从函数返回指向该数组的指针。