![](/img/trans.png)
[英]Why does this std::function and operator cause a segmentation fault?
[英]Using template call std::less<int>::operator() cause segmentation fault
我使用模板編寫跳過列表。 當我運行它時,我在調用函數insert
時遇到了分段錯誤。並且我用gdb進行了調試,它告訴我問題的原因是因為調用了std::less<int>::operator()
。我已經看到了示例 ,但是我還是為什么我錯了。 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)
該問題與std::less<>
無關。 在此時的第一個insert()
調用中:
if ( _M_keycmp(x->key, key) )
x
是空指針。 正是這種取消引用導致了分段錯誤,而不是對_M_keycmp
的調用中的_M_keycmp
。
旁注:您的所有成員名稱都是C ++中的保留字。 來自[lex.name]:
每個包含雙下划線
__
或下划線后跟大寫字母的標識符都保留給實現以供任何使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.