Trie在c中的实现

Trie在c中的实现,c,trie,C,Trie,我正在用C实现多位trie。当我运行代码时,我得到运行时错误:总线错误(内核转储)。当我通过调用insert\u rule方法添加不同的节点时,我遇到了这个错误 我用代码写评论来理解 这段代码是以multibit.h头文件的形式编写的,这个方法是从另一个.c文件调用的。c文件中的代码完全正确。我还通过示例测试代码检查了init_mtnode方法。Init_mtnode方法也非常好 #define STRIDE 3 /* each node in trie is struct o

我正在用C实现多位trie。当我运行代码时,我得到运行时错误:总线错误(内核转储)。当我通过调用insert\u rule方法添加不同的节点时,我遇到了这个错误

我用代码写评论来理解

这段代码是以multibit.h头文件的形式编写的,这个方法是从另一个.c文件调用的。c文件中的代码完全正确。我还通过示例测试代码检查了init_mtnode方法。Init_mtnode方法也非常好

    #define STRIDE 3

    /* each node in trie is struct of c code*/
    struct MtNode{
        /* nodes is an array 8 elements. Each element is a pointer to its child node.*/
        struct MtNode* nodes[8];  // 2^stride = 2^3 = 8
        int   nexthop;
    };

    typedef struct MtNode node;

    struct MtNode* helper(MtNode *curr_node, uint32_t prefix_r, int prelen, int portnum, int b);
    uint32_t* paddingFunction(uint32_t prefix_r, int prelen, int padded_prelen);

    /* Initialize multibit trie node */
    node* init_mtnode(){
        node *ret;
        int size;
        ret = static_cast<node *>(malloc(sizeof(node)));
        if (ret == NULL) /* check for NULL */
            return NULL;
        size = 2 << STRIDE;
        if (size >= 8)
            size = 7; /* maximum possible value */
        for (int i = 0 ; i < size ; ++i)
               ret->nodes[i] = NULL;
        ret->nexthop = -1;
        return ret;
    }

    /* Clean up binary trie */
    void free_mt(struct MtNode *root){
        for(int i = 0; i < (int)pow(2,STRIDE); i++){
        free_mt(root->nodes[i]);
        }    
        free(root);
    }

    /* Insert a rule */
    /* prefix is a 32 bit integer. But its "prelen (MSB - prefix length bits)" bits are counted */
    /* prelen - prefix length = Mask "
    /* portnum - port number to be saved as next hop*/
    void insert_rule(struct MtNode* root, uint32_t prefix, int prelen, int portnum){

        static int n_rules = 0;    
        n_rules ++;
        printf("rules: %d\n", n_rules);

        if( prelen == 0){
            root->nexthop = portnum;
            return;
        }
        if(prelen % STRIDE == 0){
            root = helper(root, prefix, prelen, portnum, 0);
        }else{
            int expansion = STRIDE - (prelen%STRIDE); 
            int padded_prelen = prelen + expansion;
            uint32_t *prefixes;
            prefixes = paddingFunction(prefix, prelen, padded_prelen);
            for(int i = 0; i < (int)pow(2,expansion); i++){
                root = helper(root, *(prefixes + i) , padded_prelen, portnum, 0);
            }
            free(prefixes);
        }       
    }

struct MtNode* helper(struct MtNode* curr_node, uint32_t prefix, int prelen, int portnum, int b){
    //printf("%u\n", prefix_r);
    uint32_t  temp_prefix = prefix; 
    if(b==prelen){
       curr_node->nexthop = portnum;    
       return curr_node;        
    }

    /* get first 3 bits of prefix as index*/
    temp_prefix = (prefix << b);
    temp_prefix = temp_prefix & 0xE0000000;
    temp_prefix = temp_prefix >> 29;
    int index = (int) temp_prefix;


    if(curr_node->nodes[index] == NULL){
        curr_node->nodes[index] = init_mtnode();
    }

    curr_node->nodes[index] = helper(curr_node->nodes[index], prefix, prelen, portnum, b+STRIDE);
    return curr_node;   
}

/* this method pads '0's and '1's if prefix is not divisible by STRIDE
   if prefix = 1111* , it returns array [111100 , 111101 , 1111111]*/

uint32_t *paddingFunction(uint32_t prefix_r, int prelen, int padded_prelen){
    int expansion = padded_prelen - prelen;
    int size = (int) pow(2,expansion);
    uint32_t *arr = (uint32_t *)malloc(size*sizeof(uint32_t));
    for(int i = 0; i < size; i++){
        uint32_t temp = i;
        temp = temp << (31-prelen);
        arr[i] = prefix_r | temp; 
    }
    return arr;
}
#定义步幅3
/*trie中的每个节点都是c代码的结构*/
结构MtNode{
/*节点是一个数组,包含8个元素。每个元素都是指向其子节点的指针*/
结构MtNode*节点[8];//2^stride=2^3=8
int nexthop;
};
类型定义结构MtNode节点;
结构MtNode*helper(MtNode*curr\u node,uint32\u t prefix\u r,int prelen,int portnum,int b);
uint32_t*填充函数(uint32_t前缀、int prelen、int padded_prelen);
/*初始化多位trie节点*/
node*init_mtnode(){
节点*ret;
整数大小;
ret=静态_cast(malloc(sizeof(node));
如果(ret==NULL)/*检查NULL*/
返回NULL;
尺寸=2=8)
大小=7;/*最大可能值*/
对于(int i=0;inodes[i]=NULL;
ret->nexthop=-1;
返回ret;
}
/*清理二进制trie*/
无空\u mt(结构节点*根){
对于(int i=0;i<(int)功率(2,跨步);i++){
自由(根->节点[i]);
}    
自由根;
}
/*插入规则*/
/*前缀是32位整数。但它的“prelen(MSB-前缀长度位)”位被计数*/
/*prelen-前缀长度=掩码“
/*portnum-要保存为下一个跃点的端口号*/
void insert_规则(struct MtNode*root,uint32_t前缀,int prelen,int portnum){
静态int n_规则=0;
n_规则++;
printf(“规则:%d\n”,n\u规则);
if(prelen==0){
root->nexthop=portnum;
回来
}
如果(初始步幅百分比==0){
root=helper(root,前缀,prelen,portnum,0);
}否则{
int扩展=步幅-(初始步幅百分比);
int padded_prelen=prelen+扩展;
uint32_t*前缀;
前缀=paddingFunction(前缀,prelen,padded_prelen);
对于(int i=0;i<(int)pow(2,扩展);i++){
root=helper(root,*(前缀+i)、padded_prelen、portnum、0);
}
免费(前缀);
}       
}
struct MtNode*helper(struct MtNode*curr\u node,uint32\u t前缀,int prelen,int portnum,int b){
//printf(“%u\n”,前缀“\u r”);
uint32温度前缀=前缀;
如果(b==prelen){
curr\u node->nexthop=portnum;
返回当前节点;
}
/*获取前缀的前3位作为索引*/
临时前缀=(前缀>29;
int索引=(int)临时前缀;
if(当前节点->节点[索引]==NULL){
curr_node->nodes[index]=init_mtnode();
}
curr\u node->nodes[index]=helper(curr\u node->nodes[index],前缀,prelen,portnum,b+STRIDE);
返回当前节点;
}
/*如果前缀不能被步长整除,则此方法将填充“0”和“1”
如果prefix=1111*,则返回数组[1111001111011111111]*/
uint32_t*填充函数(uint32_t前缀、int prelen、int padded_prelen){
int扩展=加垫预紧-预紧;
int size=(int)pow(2,扩展);
uint32_t*arr=(uint32_t*)malloc(尺寸*sizeof(uint32_t));
对于(int i=0;itemp=temp调用
helper()函数的行

root = helper(root, *(prefixes + i) , prelen, portnum, 0);
你应该通过
padded_prelen
来代替
prelen
,因为你每次都以
步幅
长度增加b。如果你将其与
prelen
进行比较,它将永远不会等于这个值,除非

prelen % STRIDE == 0

尝试使用调试器,检查问题的确切位置,然后选择一种语言,C和C++是非常不同的语言。谢谢@ IHAROB!!……我会想出……这个代码> *(前缀+i)< /C>绝对是不必要的,只使用<代码>前缀[I]
。谢谢……几分钟前我也找到了……现在我正在处理segfault错误……谢谢@shorya gupta