使用模板调用 std::less<int>::operator() 导致分段错误
Posted
技术标签:
【中文标题】使用模板调用 std::less<int>::operator() 导致分段错误【英文标题】:Using template call std::less<int>::operator() cause segmentation fault 【发布时间】:2016-03-03 13:39:34 【问题描述】:我使用模板来编写跳过列表。当我运行它时,当我调用函数insert
时出现分段错误。我用gdb 调试它告诉我问题原因,因为调用std::less<int>::operator()
。我看到了example,但我仍然是我的原因错误的。
skiplist.h:
#include <iostream>
#include <cstring>
namespace IceCity
const double DEFAULT_PROBILITY = 1/4;
const int DEFAULT_MAXSIZE = 16;
//node base
template <typename KeyValue,typename Value>
struct sklist_node
KeyValue key;
Value value;
sklist_node<KeyValue,Value>** forward;
;
template <typename KeyValue,typename Value,
typename KeyCmp = std::less<KeyValue> ,
typename ValueCmp = std::equal_to<Value> >
class sklist
public:
sklist (int limitlevel = DEFAULT_MAXSIZE, double pro = DEFAULT_PROBILITY) :
_M_limitlevel(limitlevel), _M_pro(pro)
_M_maxlevel = 0;
_M_header = make_node(limitlevel, 0, 0);
virtual ~sklist ()
//TODO:free
_M_NodePointer x = _M_header;
_M_NodePointer tmp = x->forward[0];
while (tmp != nullptr)
delete x;
x = tmp;
tmp = tmp->forward[0];
;
//Data member
private:
typedef sklist_node<KeyValue,Value> _M_Node;
typedef sklist_node<KeyValue,Value>* _M_NodePointer;
typedef Value* _M_ValuePoiner;
int _M_limitlevel;
double _M_pro;
_M_NodePointer _M_header;
KeyCmp _M_keycmp;
ValueCmp _M_valuecmp;
int _M_maxlevel;
//private member function
private:
/****
* make a node with level and key *
****/
inline _M_NodePointer
make_node(int level, KeyValue key, Value value)
_M_NodePointer res = new _M_Node;
res->key = key;
res->value = value;
res->forward = new _M_NodePointer [level+1];
return res;
/****
* creat an rand number [0.0,1.0) *
****/
inline double
random_pro()
return static_cast<double>(rand())/RAND_MAX;
/****
* get the level for a node *
****/
int
random_level()
int level = 0;
while ( random_pro() < _M_pro && level < _M_limitlevel )
level++;
return level;
public:
/****
* insert an node in skiplist *
****/
void
insert(KeyValue key, Value NewValue)
_M_NodePointer x = _M_header;
_M_NodePointer update[_M_limitlevel+1];
memset( update, 0, _M_limitlevel+1 );
for(int i = _M_maxlevel; i >=0 ; --i)
while (x->forward[i] != nullptr && _M_keycmp(x->forward[i]->key, key))
x = x->forward[i];
update[i] = x;
x = x->forward[0];
/****
* if x->key equal to search key update it
* else insert it*
****/
if ( _M_keycmp(x->key, key) )
x->value = NewValue;
else
int level = random_level();
if ( level > _M_maxlevel )
for(int i = _M_maxlevel+1; i <= level; ++i)
update[i] = _M_header;
// update maxlevel
_M_maxlevel = level;
x = make_node( level, key, NewValue );
for( int i = 0; i <= level; ++i )
x->forward[i] = update[i]->forward[i];
update[i]->forward[i] = x;
;
#endif /* ifndef IC_BASE_LIST */
skiplist.cpp:
#include "base_list.h"
#include <iostream>
int main(int argc, char *argv[])
IceCity::sklist<int, int> ss;
for (int i = 0; i < 20; ++i)
ss.insert(i, i*10);
return 0;
错误消息:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401894 in std::less<int>::operator()(int const&, int const&) const ()
[0] from 0x0000000000401894 in std::less<int>::operator()(int const&, int const&) const
(no arguments)
[1] from 0x0000000000401286 in IceCity::sklist<int, int, std::less<int>, std::equal_to<int> >::insert(int, int)
(no arguments)
【问题讨论】:
【参考方案1】:问题与std::less<>
无关。此时在您的第一个insert()
呼叫中:
if ( _M_keycmp(x->key, key) )
x
是一个空指针。正是取消引用导致了分段错误,而不是对 _M_keycmp
的调用中的任何内容。
旁注:您所有的成员名称都是 C++ 中的保留字。来自 [lex.name]:
每个包含双下划线
__
或以下划线后跟大写字母的标识符都保留给实现以供任何使用。
【讨论】:
以上是关于使用模板调用 std::less<int>::operator() 导致分段错误的主要内容,如果未能解决你的问题,请参考以下文章
我的C/C++语言学习进阶之旅解决使用algorithm库里面的sort函数的时候,编译报错:未能使函数模板“unknown-type std::less<void>::operator ()(代码片
我的C/C++语言学习进阶之旅解决使用algorithm库里面的sort函数的时候,编译报错:未能使函数模板“unknown-type std::less<void>::operator ()(代码片