You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中引用字符数组引发栈溢出的原因及性质疑问

C语言中引用字符数组引发栈溢出的原因及性质疑问

先给你明确结论:这绝对是真实的运行时错误,不是IDE的虚假警告。栈溢出检测是编译器/操作系统的内存保护机制触发的,说明你的代码已经破坏了栈内存的完整性——这次碰巧输出了正确结果纯属运气,属于C语言里的“未定义行为”,下次运行可能直接崩溃、输出乱码,甚至引发更严重的问题。

下面给你拆解代码里的两个核心问题:

1. memset调用的致命错误

你在函数里写了:

memset(arr, 0, sizeof(arr));

这里的arr是函数参数里的char*指针——在C语言中,当你把数组名传递给函数时,它会自动退化为指针类型。所以sizeof(arr)计算的是指针本身的大小(64位系统是8字节,32位是4字节),而不是原字符数组str的实际大小。

原数组str定义为char str[] = "1 2";,它的实际大小是4字节(包含字符'1'、' '、'2'和末尾的\0)。当你用memset往这个数组里写入超过4字节的内容时,就会覆盖栈上数组后面的其他数据(比如函数的返回地址、其他局部变量),直接触发栈溢出检测机制。

2. 数组空间不足导致越界写入

原数组str只有4字节的空间,但处理后的结果是"10 20",加上末尾的\0一共需要6字节的空间。你用strcat把这些内容拼接到arr时,会超出原数组的边界,继续往栈上的其他内存区域写数据,这同样会破坏栈的结构,也是触发错误的原因之一。

修正方案

要解决这个问题,核心是让函数知道目标数组的大小,或者确保数组有足够空间容纳结果。这里给你一个安全的修改版本:

修改后的函数

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

void read_and_mul(char *arr, size_t arr_size, int scale) {
    int num_arr[2];
    char *ch = strtok(arr, " ");
    num_arr[0] = scale * atoi(ch);
    ch = strtok(NULL, " ");
    num_arr[1] = scale * atoi(ch);

    // 用arr_size限制memset的范围,避免越界
    memset(arr, 0, arr_size);

    // 用snprintf替代sprintf+strcat,自动处理缓冲区大小,防止溢出
    snprintf(arr, arr_size, "%d %d", num_arr[0], num_arr[1]);
}

修改后的main函数

int main(int argc, char *argv[]) {
    // 定义足够大的数组,确保能容纳处理后的结果
    char str[20] = "1 2";
    // 直接传数组名即可,无需强制转换为(char*)&str
    read_and_mul(str, sizeof(str), 10);
    printf("string after call: %s\n", str);
    return 0;
}

额外提醒几个细节:

  • 不要用(char *)&str这种多余的写法,数组名本身会退化为指向首元素的指针,直接传str就行
  • 尽量用snprintf代替sprintf,前者可以指定缓冲区大小,是更安全的字符串格式化方式
  • strtok会修改原字符串(把分隔符替换为\0),如果需要保留原字符串,记得先做拷贝

备注:内容来源于stack exchange,提问作者HeapUnderStop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 15:44:51