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

C字符串中出现无法解释的额外字符问题求助

问题分析与修复方案

核心问题

  1. strlen的工作逻辑:strlen会从字符串起始地址开始读取字节,直到遇到第一个'\0'(空终止符)才停止,返回的是终止符前的字符总数。你的代码中从未手动添加这个终止符,且malloc分配的内存是未初始化的垃圾值,因此strlen会一直读取超出你分配的内存范围,直到在某个随机位置碰到'\0',这就是返回值随机且偏大的根本原因。

  2. 循环导致的缓冲区溢出:你的while (i < size - 1)条件配合嵌套的for循环,会导致写入超出malloc分配的内存范围。例如当size=30时,第一次for循环会把i从0加到25,此时25 < 29(size-1=29),会再次执行for循环,i会继续增加到25+26=51,完全超出了malloc(30)分配的内存空间,这属于缓冲区溢出的未定义行为,进一步加剧了strlen结果的随机性。

修复步骤与代码

要让strlen返回预期的size值,需要做到两点:

  • 分配内存时多留1字节存放'\0'
  • 用安全的逻辑填充字符,并在最后添加终止符

修复后的代码:

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

int main()
{
    char *letters;
    int size, i = 0;

    scanf("%d", &size);
    if (size < (1024 * 1024)) {
        // 多分配1字节用于存放字符串终止符'\0'
        letters = malloc(size + 1);
        if (letters != NULL) {
            // 循环填充A-Z字符,避免缓冲区溢出
            while (i < size) {
                letters[i] = 'A' + (i % 26);
                i++;
            }
            // 必须添加字符串终止符,否则strlen会读取垃圾值
            letters[size] = '\0';
            
            printf("%lu\n", strlen(letters));
            free(letters);
        }
    } else {
        printf("Too much memory requested.\n");
    }
    return 0;
}

补充说明

  • 如果坚持只分配size字节内存,无法让strlen返回size——因为strlen必须依赖'\0'终止,此时最多只能让strlen返回size-1(将最后一个字节设为'\0')。
  • 原代码的嵌套循环逻辑存在严重的越界风险,改用i % 26的方式循环生成A-Z字符,既能简化代码,又能保证不会超出分配的内存范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 21:37:35