为什么使用 C 引用这个 char 数组会导致堆栈崩溃?

问题描述 投票:0回答:1

该程序采用一个指向 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 警告以及导致它的原因是什么?

c pointers stack clion stack-smash
1个回答
0
投票

该函数必须构建包含 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
则再次尝试写入数组外部的内存。

要解决此问题,您应该在函数内动态分配一个新的字符数组,其中将存储结果字符串,并从函数返回指向该数组的指针。

© www.soinside.com 2019 - 2024. All rights reserved.