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

C语言read系统调用输入超16字符时程序挂起问题求助

问题根源:野指针导致的未定义行为

你的代码里最致命的问题是这行:

char *s;

这里你只声明了一个字符指针,但没有为它分配任何实际的内存空间——这是一个典型的野指针。read系统调用会尝试把用户输入的字节写入这个指针指向的地址,但这个地址是完全不确定的(可能指向栈上的随机区域、已被占用的内存,甚至是内核空间)。

当输入较短时,运气好的话,你可能刚好写到了一块暂时没被用到的内存,程序还能勉强运行;但输入超过16字符时,你覆盖了更关键的内存区域(比如函数的返回地址、栈帧的其他变量),这就触发了未定义行为,表现为程序挂起、崩溃或者其他奇怪的现象。

修复方案:为指针分配合法内存

有两种常见的修复方式,根据你的需求选择即可:

1. 使用栈上的数组(简单直接,适合小内存场景)

把野指针替换为固定大小的栈数组,确保read有合法的内存可以写入:

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

int main() {
    // 分配101字节的栈内存:最多存100个输入字符 + 1个终止符
    char s[101];
    int a = read(0, s, 100);
    
    // 先检查read是否成功(避免返回-1时访问s[-1]的越界错误)
    if (a == -1) {
        perror("Failed to read input");
        return 1;
    }
    
    // 处理换行符:如果最后一个字符是换行,替换为终止符
    if (a > 0 && s[a-1] == '\n') {
        s[a-1] = '\0';
    } else {
        // 没读到换行的情况(比如输入满100字符,或用户直接按EOF),手动加终止符
        s[a] = '\0';
    }
    
    printf("\"%s\" \n read returned: %i; NUL at: %u\n", s, a, strlen(s));
    return 0;
}

2. 使用动态内存分配(适合需要灵活内存大小的场景)

如果需要更灵活的内存(比如不确定输入上限),可以用malloc分配内存,记得用完后释放:

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

int main() {
    // 动态分配101字节,检查分配是否成功
    char *s = malloc(101);
    if (!s) {
        perror("Failed to allocate memory");
        return 1;
    }
    
    int a = read(0, s, 100);
    if (a == -1) {
        perror("Failed to read input");
        free(s); // 出错时也要记得释放内存
        return 1;
    }
    
    if (a > 0 && s[a-1] == '\n') {
        s[a-1] = '\0';
    } else {
        s[a] = '\0';
    }
    
    printf("\"%s\" \n read returned: %i; NUL at: %u\n", s, a, strlen(s));
    
    free(s); // 释放动态分配的内存,避免泄漏
    return 0;
}

额外注意点

  • 永远不要使用未初始化的指针进行写入操作,这是C语言中最常见的bug来源之一
  • 一定要检查read、malloc这类系统调用/库函数的返回值,避免错误扩散
  • 字符串必须以'\0'结尾,否则printf、strlen这类字符串函数会出现未定义行为

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:18:07