C++ StringBuilder类异常:GetString()重复输出直至强制退出
StringBuilder类无限输出问题修复
我在完成作业时需要实现一个用于快速字符串拼接的StringBuilder类,要求用动态数组存储字符串,实现Append(string)等方法,其中GetString()需要在堆上生成所有已添加字符串拼接后的完整字符串。但现在GetString()函数会不断重复输出“hello”,直到在Xcode中强制退出程序,不清楚哪里出了问题。
原代码
头文件(StringBuilder.hpp)
#pragma once #include <string> using namespace std; class StringBuilder { public: StringBuilder(); //~StringBuilder(); void GetString(); void AppendAll(string*, int); void Length(); void Clear(); void Append(string userString); void DoubleArray(string*& allWords, int newCapacity); private: string* p_array; int capacity = 5; };
实现文件(StringBuilder.cpp)
#include "StringBuilder.hpp" #include <iostream> #include <string> using namespace std; void StringBuilder::Append(string userString) { int nextWordPosition = 0; for(int i=0; i < capacity ; i++) { p_array[i] = userString; cout << p_array[i] << endl; nextWordPosition +=1; if(capacity == nextWordPosition) { capacity *=2; DoubleArray(p_array, capacity * 2); } } nextWordPosition++; } void StringBuilder::DoubleArray(string*& allWords, int newCapacity) { string* p_temp = new string[newCapacity]; for(int i =0; i < newCapacity / 2; i++) { p_temp[i] = allWords[i]; } delete[] allWords; allWords = p_temp; } void StringBuilder:: GetString() { for(int i=0; i < capacity ; i++) { cout << p_array[i]<< endl; } }
主文件(main.cpp)
#include <iostream> #include <string> #include "StringBuilder.hpp" using namespace std; int main() { string testString = "hello"; string test = "world!"; StringBuilder Builder1; Builder1.Append(testString); Builder1.Append(test); Builder1.GetString(); return 0; }
问题根源
- 野指针未初始化:构造函数未实现,
p_array是野指针,直接赋值会触发未定义行为。 - Append逻辑完全错误:
- 每次调用
Append都会遍历整个capacity大小的数组,把传入的字符串赋值给每一个元素,一次Append就填满整个数组。 - 循环中不断扩容
capacity,导致i < capacity的循环条件永远无法满足(capacity增长速度比i快),Append会无限执行,不断输出字符串直到内存耗尽。 nextWordPosition是局部变量,每次Append都重置为0,无法记录实际添加的元素位置。
- 每次调用
- GetString逻辑不符合要求:当前代码只是遍历容量输出所有数组元素,没有拼接字符串,也没有区分有效元素和未使用的数组空间。
- 缺少有效元素计数:类中只有记录数组容量的
capacity,没有记录实际添加元素数量的变量,无法区分有效数据。
修复后的代码
头文件(StringBuilder.hpp)
#pragma once #include <string> using namespace std; class StringBuilder { public: StringBuilder(); ~StringBuilder(); // 析构函数释放内存 string GetString(); // 返回拼接后的完整字符串 void Append(string userString); void Clear(); int Length(); // 返回拼接后字符串的总长度 private: string* p_array; int capacity = 5; int size = 0; // 记录实际添加的元素个数 void DoubleArray(); // 简化扩容逻辑 };
实现文件(StringBuilder.cpp)
#include "StringBuilder.hpp" #include <iostream> #include <string> using namespace std; StringBuilder::StringBuilder() { // 初始化动态数组 p_array = new string[capacity]; } StringBuilder::~StringBuilder() { // 释放动态数组内存 delete[] p_array; } void StringBuilder::Append(string userString) { // 容量不足时扩容 if (size >= capacity) { DoubleArray(); } // 添加新字符串到数组末尾 p_array[size] = userString; size++; } void StringBuilder::DoubleArray() { capacity *= 2; string* p_temp = new string[capacity]; // 复制原有有效元素 for (int i = 0; i < size; i++) { p_temp[i] = p_array[i]; } delete[] p_array; p_array = p_temp; } string StringBuilder::GetString() { // 在堆上生成拼接后的字符串 string* result = new string(); for (int i = 0; i < size; i++) { *result += p_array[i]; } return *result; } void StringBuilder::Clear() { size = 0; // 重置容量并释放多余内存 delete[] p_array; capacity = 5; p_array = new string[capacity]; } int StringBuilder::Length() { int totalLength = 0; for (int i = 0; i < size; i++) { totalLength += p_array[i].length(); } return totalLength; }
主文件(main.cpp)
#include <iostream> #include <string> #include "StringBuilder.hpp" using namespace std; int main() { string testString = "hello"; string test = "world!"; StringBuilder Builder1; Builder1.Append(testString); Builder1.Append(test); string result = Builder1.GetString(); cout << "拼接结果:" << result << endl; cout << "总长度:" << Builder1.Length() << endl; Builder1.Clear(); Builder1.Append("test"); cout << "清空后添加的结果:" << Builder1.GetString() << endl; return 0; }
修复说明
- 内存管理修正:实现构造函数初始化数组,析构函数释放内存,解决野指针和内存泄漏问题。
- Append逻辑修正:只在数组末尾添加新元素,容量不足时才扩容,用
size变量记录实际添加的元素数量。 - GetString实现要求:在堆上创建字符串对象,遍历所有有效元素完成拼接,返回符合要求的完整字符串。
- 简化扩容逻辑:直接使用类成员变量完成扩容,只复制有效元素,避免不必要的操作。
- 完善实用方法:补充
Clear清空方法和Length长度统计方法,符合StringBuilder的常用功能。
内容的提问来源于stack exchange,提问作者Kelsie B
相关产品推荐
相关产品推荐

