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

如何在GetOutliers方法中返回string指针避免std::bad_alloc错误

问题描述

我尝试让GetOutliers()方法返回string指针以通过测试用例,但一直失败,报错:

FAILED: {Unknown expression after the reported line} due to unexpected exception with message: std::bad_alloc

试过不用指针定义方法,但测试用例里执行string* outlier = bama.GetOutliers(),要求必须返回指针,这条路走不通。也试过返回存储字符串的数组指针,结果还是触发同样的错误。需要解决怎么返回字符串并通过测试用例的问题。

错误尝试1

string* State::GetOutliers(){
    vector<string>outliers;
    double mean = GetMeanDeaths();
    double std = Stdev();
    int deathNum = week->GetDeathCount();
    string getOut = " - total deaths: ";
    string death = to_string(deathNum);
    string week = week; // 错误:自身赋值,未获取对应周的日期
    string* totalString;
    string sentence;
    int outCount; // 未初始化

    for(int i = 0; i<numberOfDataPoints;i++){
        if(deathNum >= (2*std+mean)){ // 判断逻辑与测试用例不符
            sentence = week+getOut+death;
        }
        outCount++;
    }
    totalString = &sentence; // 返回局部变量地址,函数结束后sentence被销毁
    return totalString;
}

错误尝试2

string* State::GetOutliers(){
    vector<string>outliers;
    double mean = GetMeanDeaths();
    double std = Stdev();
    int deathNum = week->GetDeathCount(); // 仅获取单个周的死亡数,未遍历所有周
    string getOut = " - total deaths: ";
    string death = to_string(deathNum);
    string week = week; // 自身赋值错误
    string totalString;
    string stringArray[numberOfDataPoints]; // 局部数组,函数结束后销毁;若numberOfDataPoints非编译期常量,属于C++标准不支持的变长数组

    string sentence;
    int outCount; // 未初始化

    for(int i = 0; i<numberOfDataPoints;i++){
        if(deathNum >= (2*std+mean)){
            totalString = week+getOut+death;
            stringArray[i] = totalString;
        }
        outCount++;
    }
    return stringArray; // 返回局部数组地址,形成野指针
}

测试用例

TEST_CASE("Testing State object")
{
    State bama("Alabama");
    CHECK("Alabama" == bama.GetName());

    bama.AddWeek("2020-05-02,2000");
    bama.AddWeek("2020-05-09,2000");
    bama.AddWeek("2020-05-16,100");
    bama.AddWeek("2020-05-23,2000");
    bama.AddWeek("2020-05-30,2000");
    bama.AddWeek("2020-06-06,2000");

    CHECK(Approx(1683.33).epsilon(0.01) == bama.GetMeanDeaths());

    CHECK(Approx(708.08).epsilon(0.01) == bama.Stdev());

    CHECK(1 == bama.GetOutlierCount());
    std::string* outliers = bama.GetOutliers();
    CHECK("2020-05-16 - total deaths: 100" == outliers[0]); //TEST CASE FOR GetOutliers()
    delete [] outliers;
}
解决方案

核心错误分析

  1. 野指针问题:两个尝试都返回了局部变量(局部字符串/局部数组)的地址,函数执行完毕后局部变量会被销毁,返回的指针变成野指针,访问时触发未定义行为(如std::bad_alloc或程序崩溃)。
  2. 逻辑错误:未遍历所有周的数据,仅使用单个周的死亡数判断;异常值判断条件与测试用例不符;存在变量自身赋值、未初始化变量等低级错误。

正确实现代码

string* State::GetOutliers(){
    double mean = GetMeanDeaths();
    double stdDev = Stdev();
    int outlierCount = GetOutlierCount();
    // 用new动态分配数组,确保内存不会在函数结束后销毁
    string* result = new string[outlierCount];
    int currentIndex = 0;

    // 假设State类中有存储所有Week对象的容器,比如vector<Week*> m_weeks;
    // 遍历每个周的数据
    for (const auto& week : m_weeks) {
        int deathNum = week->GetDeathCount();
        string weekDate = week->GetWeekDate(); // 假设Week类有获取日期字符串的方法

        // 根据测试用例修正异常值判断:100 <= 1683.33 - 2*708.08 ≈ 267.17,符合条件
        if (deathNum <= mean - 2 * stdDev) {
            string outlierStr = weekDate + " - total deaths: " + to_string(deathNum);
            result[currentIndex++] = outlierStr;
        }
    }

    return result;
}

关键注意事项

  • 动态内存分配:必须使用new string[outlierCount]分配数组,测试用例才能用delete[] outliers;正确释放内存,避免内存泄漏。
  • 遍历所有周数据:确保遍历State类中存储的所有周对象,获取每个周的日期和死亡数。
  • 修正判断条件:根据测试用例的实际异常值定义调整判断逻辑(测试用例中是低于均值2倍标准差的数值)。
  • 避免局部变量指针:绝对不能返回局部变量或局部数组的地址,这些内存会在函数退出后被回收。

内容的提问来源于stack exchange,提问作者Beri Gill

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 18:26:17