为何在自由存储区分配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
相关产品推荐
相关产品推荐

