std::string::erase引发内存损坏,求助排查C++代码问题
解决std::string::erase引发的内存损坏问题
兄弟,太懂你盯着代码二十多分钟找不到bug的崩溃感了!我一眼就瞅出你这段trimLeft函数的问题所在——迭代器和容器实例不匹配,直接导致了std::string::erase触发内存损坏。
问题根源分析
你写的函数里犯了一个典型的迭代器错误:
- 函数参数
std::string string_是值传递,意味着进入函数后它是原字符串的一个独立拷贝; - 但你传入的
begin_和end_迭代器,是属于原字符串实例的,和函数里的拷贝string_完全无关; std::string::erase要求传入的迭代器必须属于当前字符串对象,用其他实例的迭代器调用它,会直接访问非法内存,触发未定义行为(也就是你遇到的内存损坏)。
修正方案
根据你的需求,有两种常见的修正方式:
方案1:传递字符串引用(修改原字符串)
如果你想直接修改原字符串,把参数改成引用传递,这样迭代器和字符串实例就匹配了:
#include <iostream> #include <string> #include <cctype> template <typename ForwardIt> std::string& trimLeft(std::string& string_, ForwardIt begin_, ForwardIt end_) { if (!string_.empty()) { auto it = begin_; while (it != end_ && std::isspace(static_cast<unsigned char>(*it))) ++it; string_.erase(begin_, it); } return string_; }
方案2:修剪拷贝后的字符串(不修改原字符串)
如果你想返回修剪后的新字符串,不需要外部传入迭代器,直接使用拷贝字符串自己的迭代器即可:
#include <iostream> #include <string> #include <cctype> std::string trimLeft(std::string string_) { if (!string_.empty()) { auto it = string_.begin(); while (it != string_.end() && std::isspace(static_cast<unsigned char>(*it))) ++it; string_.erase(string_.begin(), it); } return string_; }
额外提醒
迭代器是和具体容器实例绑定的,不同实例的迭代器绝对不能混用——哪怕两个容器内容完全一样也不行!这是C++容器迭代器的核心规则之一,踩过一次坑之后就再也忘不了了😅
内容的提问来源于stack exchange,提问作者Poeta Kodu
相关产品推荐
相关产品推荐

