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

scanf输入超出malloc分配内存为何不崩溃?如何修复?

内存越界未崩溃的原因及修复方案

示例代码

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

int main()
{
    int len;
    char* str_input;

    printf("Enter len of str: ");
    scanf("%d", &len);

    str_input = (char*) malloc(len * sizeof(char));

    printf("Enter str. & to end: ");
    scanf("%s", str_input);

    printf("%s", str_input);
}

问题

当输入长度为1,分配1字节内存后,输入长度超过1的字符串(如"hello"),程序仍能完整打印该字符串。为何未因内存不足崩溃?该如何修复此问题?


为什么没崩溃?

这是典型的内存越界访问,没崩溃纯粹是运气使然:

  • C语言本身不做内存边界检查,malloc分配的1字节内存后面的空间,暂时仍属于当前进程的地址空间,且没有被其他关键数据(比如函数返回地址、全局变量)占用,所以写入和读取操作都没立刻触发错误。
  • 这种行为属于未定义行为——不是不会崩溃,只是这次没踩到“雷区”。换个运行环境、多执行几次,或者后续代码用到被覆盖的内存时,就可能出现崩溃、数据错乱等诡异问题。

修复方案

可以从三个层面彻底解决这个问题:

  1. 分配内存时预留字符串结束符空间
    C字符串必须以\0结尾,所以分配内存时要多留1字节空间:
str_input = (char*) malloc((len + 1) * sizeof(char));
  1. 限制输入长度,强制避免越界
    使用scanf的格式化参数限制读取长度,最多读取len个字符(预留1个位置给\0):
scanf("%.*s", len, str_input);

或者用更安全的fgets函数,它能明确限制读取的字节数,还能避免scanf遗留的换行符问题:

// 清除scanf输入len后留下的换行符
getchar();
// 最多读取len+1个字节(含\0)
fgets(str_input, len + 1, stdin);
// 去掉fgets可能读取到的换行符
size_t input_len = strlen(str_input);
if (input_len > 0 && str_input[input_len - 1] == '\n') {
    str_input[input_len - 1] = '\0';
}
  1. 检查内存分配是否成功
    malloc可能因为系统内存不足返回NULL,必须处理这种情况,避免后续操作空指针:
if (str_input == NULL) {
    fprintf(stderr, "Memory allocation failed\n");
    return 1;
}

内容的提问来源于stack exchange,提问作者nat34

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:00:56