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

为何在自由存储区分配char会出现错误值?注释delete[]后恢复正常

问题分析与解决

核心问题原因

你的代码存在三个关键错误,导致字符串处理出现未定义行为:

  • 初始字符串缺少结束符:new char[1]{'a'} 只分配1字节内存存字符'a',但C风格字符串必须以'\0'结尾。strlen会从指针位置一直向后扫描直到找到'\0',这里直接越界访问内存,导致后续所有依赖strlen的逻辑全部出错。
  • 内存分配大小不足:要在原字符串末尾添加一个字符,新内存需要的大小是 原字符串长度 + 1(新字符) + 1(结束符),也就是strlen(p)+2。你现在只分配了strlen(p)+1,空间不够存新字符和结束符。
  • 新字符串未补结束符:循环仅把新字符放到原字符串长度的位置,但没有在最后补上'\0',导致新生成的字符串依然是无效的C风格字符串,后续strlen和cout输出都会出现异常。

注释掉delete[] p后看似正常,只是因为未释放的内存碰巧在后续位置有'\0',属于运气成分,本质还是未定义行为,随时可能崩溃或输出乱码。

修正后的代码

#include <iostream>
#include <cstring>

char* add_char(char* p, char ch) 
{
    // 先获取原字符串长度,避免重复调用strlen损耗性能
    size_t len = strlen(p);
    // 分配足够内存:原长度 + 新字符 + 结束符
    char* pc = new char[len + 2];

    // 复制原字符串内容
    strcpy(pc, p);
    // 添加新字符
    pc[len] = ch;
    // 补上字符串结束符
    pc[len + 1] = '\0';

    delete[] p;
    return pc;
}

int main()
{
    char ch = 0; 
    // 初始分配2字节,同时存入'a'和结束符'\0'
    char* pc = new char[2]{'a', '\0'};

    while (std::cin >> ch && ch != '!') {
        pc = add_char(pc, ch);
    }
    std::cout << "pc : " << pc << "\n";
    std::cout << strlen(pc) << "\n";
    // 释放最后分配的内存,避免内存泄漏
    delete[] pc;
}

额外优化建议

尽量使用C++标准库的std::string,它会自动管理内存和字符串结束符,完全避免手动管理的繁琐与错误:

#include <iostream>
#include <string>

int main()
{
    char ch = 0; 
    std::string s = "a";

    while (std::cin >> ch && ch != '!') {
        s += ch;
    }
    std::cout << "s : " << s << "\n";
    std::cout << s.size() << "\n";
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:52:37