Bay*_*you 0 c++ iterator vector segmentation-fault
我用C / C ++编写代码已经有一段时间了,我已经找到解决问题的替代方法,但是我想知道为什么原始代码不起作用。
我有一个测试类,基本上只存储一个字符串。
class test {
private:
std::string name;
public:
test(std::string name) : name(name) {};
std::string get_name() { return name; }
};
Run Code Online (Sandbox Code Playgroud)
在其中,main我有一个向量,我有时会用test对象填充。下面的代码模拟了vector的不规则用法vect。
int main(void) {
std::vector<test *> vect;
std::vector<test *>::iterator i;
//* Comment this for a working example
std::cout << "Searching empty vector" << std::endl;
i = *(_is_in_vector(vect, std::string("test 3")));
if (i == vect.end()) {
std::cout << "Nothing found" << std::endl;
} // */
vect.push_back(new test("test 1"));
vect.push_back(new test("test 2"));
vect.push_back(new test("test 3"));
std::cout << "All:" << std::endl;
i = *(_is_in_vector(vect, std::string("test 3")));
if (i != vect.end()) {
std::cout << "Erase " << (*i)->get_name() << std::endl;
vect.erase(i);
delete *i;
}
i = *(_is_in_vector(vect, std::string("test 3")));
if (i == vect.end()) {
std::cout << "Nothing found" << std::endl;
}
std::cout << "Left:" << std::endl;
for (i = vect.begin(); i!=vect.end(); ++i) {
std::cout << (*i)->get_name() << std::endl;
delete *i;
}
vect.clear();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
因为在向量中搜索test对象会发生多次,所以我创建了一个函数_is_in_vector来搜索test对象并将迭代器返回给它。
static std::vector<test *>::iterator * _is_in_vector(std::vector<test *> &vect, std::string find) {
std::string identity = find;
static std::vector<test *>::iterator i = vect.begin();
std::cout << "Vect size: " << vect.size() << std::endl;
for (i; i != vect.end(); ++i) {
std::string tmp = (*i)->get_name(); /* Segmentation fault after filling vector*/
if (0 == identity.compare(tmp)) break;
}
return &i;
}
Run Code Online (Sandbox Code Playgroud)
问题是,当我注释掉。中的Searching empty vector部分时,上面的代码有效main。一旦向量充满test对象,我_is_in_vector第二次打电话。此函数中的向量确实具有三个条目,但(*i)所有都指向NULL。
输出:
Searching empty vector
Vect size: 0
Nothing found
All:
Vect size: 3
Segmentation fault
Run Code Online (Sandbox Code Playgroud)
预期产量:
Searching empty vector
Vect size: 0
Nothing found
All:
Vect size: 3
Erase test 3
Vect size: 2
Nothing found
Left:
test 1
test 2
Run Code Online (Sandbox Code Playgroud)
首先,不清楚为什么需要test通过指针而不是通过值存储对象。如果确实需要,请使用智能指针。
至于您的问题,为什么要返回指向迭代器的指针?这是问题的根本原因-使&i返回的结果合法static,但static局部变量仅初始化一次,并且不会更改btw调用的值-因此,在首次调用后,它指向向量中的一个元素,但随后您添加了元素并使所有迭代器(包括静态)i无效,会分割错误。因此修复很简单-按值返回迭代器并使其i为非静态但规则的,这很轻巧,这样做是完全可以的。
以PS开头的PS标识符_在全局范围内是非法的,有关详细信息,请参见此处关于在C ++标识符中使用下划线的规则是什么?
因此,您的函数实际上应如下所示:
static std::vector<test *>::iterator is_in_vector( std::vector<test *> &vect, const std::string &find)
{
return std::find_if( vect.begin(), vect.end(), [find]( test *p ) {
return p->get_name() == find;
} );
}
Run Code Online (Sandbox Code Playgroud)
假设向量永远不应该保持nullptr,如果是这种情况或为了安全起见更改条件为:
return p && p->get_name() == find;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
74 次 |
| 最近记录: |