这是我的代码。
#include<stdio.h>
#include<stdlib.h>
struct prefix {
unsigned int IP ;
unsigned char len ;
struct prefix *next ;
};
typedef struct prefix Prefix ;
int cal(int d){
int i , sum ;
sum = 2 ;
for( i = 0 ; i < d-1 ; i++)
sum = sum * 2 ;
return sum+1 ; }
Prefix *insert_a_node(Prefix *head,Prefix *node ){
Prefix *cur ;
cur = head ;
if(head == NULL)
return node ;
if( node == NULL )
return head ;
if( node->IP < head->IP)
{ node->next = head ;
return node ; }
while( cur->next != NULL && cur->next->IP <= node->IP)
cur = cur->next ;
node->next = cur->next ;
cur->next = node ;
return head ;
}
void insert_prefix(Prefix *group_head,Prefix *node){
int i = 0;
Prefix *t;
if(node == NULL) return;
if(group_head->next == NULL)
{
group_head->next=node;
return ;
}
if(node->IP <= group_head->next->IP)
{
node->next = group_head->next ;
group_head->next=node;
return ;
}
t = group_head->next ;
if(t->next==NULL)
{ t->next=node;
return;}
while(t->next!=NULL && t->next->IP < node->IP)
t=t->next;
if(t->next==NULL)
{ t->next=node;
return;}
else{
node->next=t->next;
t->next=node;
return;}
}
Prefix *build_list_no_order(Prefix *head,Prefix *node){
if (head == NULL)
return node ;
if (node == NULL)
return head ;
Prefix *cur ;
cur = head ;
while ( cur->next != NULL)
cur = cur->next ;
cur->next = node ;
return head ;
}
Prefix *build_routing_table(){
int a[5],i ;
int ip = 0 ;
Prefix *head ;
head = NULL ;
FILE *ofp ;
ofp = fopen("routing_table","r") ;
while( fscanf(ofp,"%d.%d.%d.%d/%d",&a[0],&a[1],&a[2],&a[3],&a[4]) != EOF){
Prefix *node = (Prefix*)malloc(sizeof(Prefix)) ;
for ( i =0 ; i < 4 ; i++)
{ ip = ip + a[i] ;
if ( i != 3 )
ip = ip<<8 ; }
node->IP = ip ;
ip = 0 ;
node->len=a[4];
head = build_list_no_order(head,node); }
fclose(ofp);
return head ;
}
void segment(int d,Prefix *rout ,Prefix group[],int each_seg_num[]){
int index=0,i;
if(rout->len < d)
index = cal(d)-1;
else{
for(i=31 ; i>31-d ; i--){
if( ( rout->IP & 1<<i ) && ( i!=32-d))
{index++;
index=index<<1;}
if( (rout->IP & 1<<i) && i==32-d)
index++;
if( !(rout->IP & 1<<i) && i!=32-d)
index=index<<1;
}
}
each_seg_num[index]++;
insert_prefix(&group[index],rout);
return ;
}
int main ( int argc , char *argv[]){
Prefix *routing_head;
Prefix *trace_head;
Prefix *node;
int d = 5 , i ; //need use argc finally
int group_num;
group_num = cal(d);
Prefix group[group_num] ;
int each_seg_num[group_num];
for( i = 0 ; i < group_num ; i++)
each_seg_num[i] = 0;
routing_head = build_routing_table();
int count = 1200 ;
while(routing_head != NULL &&count>=0){
node = routing_head ;
routing_head = routing_head->next ;
node->next = NULL ;
segment(d,node,group,each_seg_num);
count--;
}
for( i = 0 ; i < group_num ; i++)
printf("%d\n",each_seg_num[i]);
return 0 ;
}
让我解释一下我现在在做什么。
首先,我从routing_table读取了80000个数据(每个数据都有相似之处)
格式如2.10.120.20/8,我将它存储在Prefix的IP(unsigned int)中,你可以称之为IP /前缀长度。)
然后,我想将这些数据分段到不同的组(每组是
一个链表)数字由int d决定,假设d = 2,所以
我有2 ^ 2 + 1组。由于每个数据的第一个&#34; d&#34;我们可以确定哪个
小组应该数据
示例:IP(二进制):01000011 ......它应该进入组[1]
IP:1000001 .....应该进入组[2]
如果前缀为len&lt; d如IP:1 ********(*表示不关心位)它应该进入特殊组,组[4]。
第三,每个链表应该按顺序(从小到大)
问题:我想我已经完成了几乎所有代码,但是当我执行我的程序时
它有分段错误。但最令我惊讶的是,当我使用int count时
限制传入segment()的数据量,程序可以正常工作!!
代码可以工作少于传递大约1000个数据。我想知道怎么做
解决我的问题,谢谢你阅读我的问题。
.....最后,我的英语可能还不够完美地解释这个问题.....请原谅我^^
答案 0 :(得分:0)
在insert_prefix
中发生崩溃,您将节点插入到组列表中,同时保持列表排序。
首先,定义组时会出现概念错误。有group_num
个组,每个组都是一个链表,所以你需要一个指针数组来代替节点数组:
Prefix *group[group_num];
您还应该将每个指针初始化为NULL
。您必须将group
参数调整为segment
和insert_prefix
函数。
在无序链表的实现中,返回新的头节点。在这里,您还必须找到更新头部的方法。在C中,我发现将指针传递给头节点指针很有用。
您可以将此指针用于节点指针以遍历列表:当您调用该函数时,该指针是头节点的地址。之后,它是前一个节点的next
指针的地址。
使用这种技术,您的功能变为:
void insert_prefix(Prefix **head, Prefix *node)
{
if (node == NULL) return;
while (*head && (*head)->IP < node->IP) {
head = &(*head)->next;
}
node->next = *head;
*head = node;
}
了解此迭代方法如何处理所有特殊情况。没有必要区分空列表和完整列表。
您应该对程序进行的其他更改是在此处更改group
参数:
void segment(int d, Prefix * rout, Prefix *group[], int each_seg_num[])
{
....
}
并更改main
中的定义和初始化:
group_num = cal(d);
Prefix *group[group_num];
int each_seg_num[group_num];
for (i = 0; i < group_num; i++) {
group[i] = NULL;
each_seg_num[i] = 0;
}
您可能还应该在程序结束时引入代码来销毁您的列表。