自定义String类中delete[] char指针致程序退出时控制台卡顿原因
问题原因分析与修复方案
兄弟,你遇到的这个退出卡顿问题,核心是内存越界写入引发的未定义行为!咱们一步步拆解来看:
核心问题点
先盯着你的String构造函数代码看:
String(const char *s) { size_t len = strlen(s); str = new char[len]; // 这里分配的内存少了1个字节! for (size_t i = 0; i < len; i++) str[i] = s[i]; str[len] = '\0'; // 这里直接越界写入了! }
strlen(s)返回的是字符串有效字符的长度,不包含末尾用来终止字符串的'\0'。比如传入"12",len的值是2。- 你用
new char[len]只分配了2个char的空间,但后续执行str[len] = '\0'时,相当于往str[2]的位置写入数据——这已经超出了你分配的内存范围,属于内存越界。
这种内存越界属于C++里的「未定义行为」,程序可能表现出各种奇怪的症状:有时看起来正常,有时直接崩溃,就像你遇到的退出时卡顿。当析构函数调用delete[] str时,内存管理器要处理这块已经被越界操作破坏的内存,自然就出问题了。
而你单独测试char指针的例子没问题,是因为那个例子里没有发生越界写入,所有内存操作都是合法的。
修复方案
1. 分配足够的内存
把构造函数里的内存分配语句改成:
str = new char[len + 1];
多分配1个字节的空间,用来存储终止符'\0',这样后续的写入操作就不会越界了。
2. 完善默认构造函数
你的默认构造函数里str成员没有初始化,要是创建了默认构造的String对象,析构时delete[]一个野指针也会触发未定义行为。建议给默认构造函数加个初始化:
String() : str(nullptr) {}
因为delete[] nullptr是C++标准允许的安全操作,不会出问题。
3. 简化复制逻辑(可选)
其实你可以直接用strcpy来简化字符串复制的代码,不用手动循环:
String(const char *s) { size_t len = strlen(s); str = new char[len + 1]; strcpy(str, s); }
内容的提问来源于stack exchange,提问作者Kobi Mizrachi
相关产品推荐
相关产品推荐

