edX C++课程字符串分割代码超内存:是代码还是平台问题?
问题结论
问题完全由代码逻辑缺陷导致,和edX平台编译器、512MB内存限制无关。核心是两个致命bug触发了无限循环+超大内存申请,瞬间耗尽可用内存才报出内存不足错误。
具体bug说明
- 第一处致命错误:
while循环缺失大括号
C++语法规定,循环/判断语句后如果不写大括号,只会将紧接的第一行代码作为执行体。你的代码中while (j != string::npos)的循环体只有v.push_back(s.substr(i, i - j));这一行,后续更新i、j值的代码完全不在循环内,j会永远停在第一次匹配到分隔符的位置,永远满足!= string::npos的循环条件,形成死循环。 - 第二处致命错误:
substr参数写反、长度计算错误std::string::substr的第一个参数是子串起始下标,第二个参数是子串长度。你写的s.substr(i, i - j)中,初始状态i=0、j是第一个分隔符的下标(正数),i-j为负数,转换为无符号类型string::size_type后会变成一个极大的正整数,相当于每次push_back都要申请一块长度接近内存上限的字符串空间,再叠加死循环的无限次插入,极短时间内就会耗光所有分配的内存。 - 冗余逻辑:循环正常结束后
j必然等于string::npos,额外加if (j == string::npos)判断完全多余。 - 不规范写法(不直接触发内存错误,但建议修正):代码中引入的
<string.h>是C语言风格字符串操作头文件,C++std::string对应的头文件是<string>;此外<functional>头文件在这段代码中没有被使用,可以直接删除,避免不必要的头文件引入。
修正后的可运行split函数实现
将原代码中的split函数替换为以下版本即可正常运行,不会触发内存错误:
void split(const string &s, char c, vector<string> &v) { string::size_type i = 0; string::size_type j = s.find(c); while (j != string::npos) { v.push_back(s.substr(i, j - i)); // 修正长度计算,j-i才是两个分隔符之间的子串长度 i = ++j; j = s.find(c, j); } // 循环结束后直接加入最后一段子串 v.push_back(s.substr(i)); }
内容的提问来源于stack exchange,提问作者Peter Smedskjaer
相关产品推荐
相关产品推荐

