如何在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; }
解决方案
核心错误分析
- 野指针问题:两个尝试都返回了局部变量(局部字符串/局部数组)的地址,函数执行完毕后局部变量会被销毁,返回的指针变成野指针,访问时触发未定义行为(如
std::bad_alloc或程序崩溃)。 - 逻辑错误:未遍历所有周的数据,仅使用单个周的死亡数判断;异常值判断条件与测试用例不符;存在变量自身赋值、未初始化变量等低级错误。
正确实现代码
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
相关产品推荐
相关产品推荐

