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

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;
    
}

问题根源

  1. 野指针未初始化:构造函数未实现,p_array是野指针,直接赋值会触发未定义行为。
  2. Append逻辑完全错误:
    • 每次调用Append都会遍历整个capacity大小的数组,把传入的字符串赋值给每一个元素,一次Append就填满整个数组。
    • 循环中不断扩容capacity,导致i < capacity的循环条件永远无法满足(capacity增长速度比i快),Append会无限执行,不断输出字符串直到内存耗尽。
    • nextWordPosition是局部变量,每次Append都重置为0,无法记录实际添加的元素位置。
  3. GetString逻辑不符合要求:当前代码只是遍历容量输出所有数组元素,没有拼接字符串,也没有区分有效元素和未使用的数组空间。
  4. 缺少有效元素计数:类中只有记录数组容量的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;
}

修复说明

  1. 内存管理修正:实现构造函数初始化数组,析构函数释放内存,解决野指针和内存泄漏问题。
  2. Append逻辑修正:只在数组末尾添加新元素,容量不足时才扩容,用size变量记录实际添加的元素数量。
  3. GetString实现要求:在堆上创建字符串对象,遍历所有有效元素完成拼接,返回符合要求的完整字符串。
  4. 简化扩容逻辑:直接使用类成员变量完成扩容,只复制有效元素,避免不必要的操作。
  5. 完善实用方法:补充Clear清空方法和Length长度统计方法,符合StringBuilder的常用功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:25:25