如何用递归反转打印文本?递归代码崩溃求排查
问题排查与修复思路
咱先捋捋你的代码里几个核心问题,这些就是导致程序崩溃和逻辑混乱的根源:
1. 函数返回类型完全错配
你的toReverse声明返回char,但你实际想做的是反转整个字符串啊!单个字符的返回类型根本承载不了这个需求,递归时每次返回的空格或字符没有被合理处理,反而会让栈里的返回值乱成一锅粥,直接触发未定义行为。
2. 值传递Text对象踩了浅拷贝的坑
你把t1作为值传递传入函数,而你的Text类有char* buffer这个指针成员——如果没给Text写正确的拷贝构造函数,值传递时会默认做浅拷贝,也就是原对象和函数里的临时t1共享同一块内存。等函数调用结束,临时t1被销毁时会释放这块内存,原对象的buffer就变成了野指针,后续一访问必然崩溃。
3. 递归终止条件和索引逻辑全错
- 第一个终止条件:
if (t1.bufferSize == 1) return ' ';——字符串长度为1时,应该输出那个唯一的字符啊,返回空格直接把字符丢了! - 第二个终止条件:
if (t == (t1.bufferSize) - 1) return ' ';——当t走到最后一个索引时直接返回空格,不仅跳过了最后一个字符,递归到这里就戛然而止,逻辑完全不完整。 - 索引计算错误:
t1.buffer[(t1.bufferSize) - 2 - t]——比如bufferSize是5,索引范围是0-4,t=0时算出来是3,t=1时是2,t=2时是1,t=3时是0,这时候t=3离终止条件的t==4还差一步,直接返回空格,等于漏掉了索引4的字符,而且正确的反转索引应该是bufferSize - 1 - t才对。
修复后的示例代码
如果你的需求是递归反转输出字符串,改成无返回值的成员函数会更合理,比如:
// 递归辅助函数,用const引用避免拷贝问题 void Text::toReverse(const Text& t1, int t) const { // 终止条件:遍历完所有字符就结束 if (t >= t1.bufferSize) { return; } // 先递归到最后一个字符,再输出,自然实现反转 toReverse(t1, t + 1); cout << t1.buffer[t]; } // 对外的入口函数,不用传参数 void Text::toReverse() const { toReverse(*this, 0); }
如果要返回一个新的反转后的Text对象,记得要正确处理内存:
// 递归辅助函数,返回反转后的Text对象 Text Text::toReverse(int t) const { if (t == bufferSize) { return Text(""); // 假设你的Text类有接受const char*的构造函数 } Text reversed = toReverse(t + 1); // 拼接当前字符到反转字符串的末尾 char* newBuffer = new char[reversed.bufferSize + 2]; strcpy(newBuffer, reversed.buffer); newBuffer[reversed.bufferSize] = buffer[t]; newBuffer[reversed.bufferSize + 1] = '\0'; Text result(newBuffer); delete[] newBuffer; // 临时内存要释放 return result; } // 入口函数 Text Text::toReverse() const { return toReverse(0); }
必须补上的关键代码
别忘了给Text类实现拷贝构造函数和析构函数,彻底解决浅拷贝的问题:
// 拷贝构造函数:深拷贝内存 Text::Text(const Text& other) { bufferSize = other.bufferSize; buffer = new char[bufferSize + 1]; // 留位置给结束符 strcpy(buffer, other.buffer); } // 析构函数:释放动态分配的内存 Text::~Text() { delete[] buffer; }
内容的提问来源于stack exchange,提问作者Emily Lerman
相关产品推荐
相关产品推荐

