Adolf K Wiseman 2022-12-21 17:05 采纳率: 70%
浏览 26
已结题

想要从文件中读取树并修改路径上节点的信息出错

用Ubuntu20.04.5的vscode运行一个读取文件中的数据进行搜索的代码,报错:
出现异常。
Segmentation fault

img


错误如图,
程序大意是把txt文件中存储的树读取出来,找到指定的叶子节点,修改其中的数据,因为父节点中参数的值由其左右子节点中参数的值生成,修改叶子节点的值需要通过父节点指针找到父节点并修改参数的值,直至根节点。
程序运行到此函数中时,经过几次if之后发生错误。文件里的数据应该不会太大呀,之前搜索树上的数据的时候文件规模为2000都没事,更新的时候500应该不会是栈溢出吧,网上找了一圈,出现这种错误的原因有很多,感觉应该是程序本身有问题,找了一下午没找到原因,有人能发现问题所在并帮助我解决问题吗?
代码头文件define_update.h如下:

/***
 * This code .h file define size and struct used.
 */

#define FILE_SIZE       500//支持的文件数量,根据需要改
#define DICT_SIZE       60//支持的数据长度
#define MATRIXinv_PATH  "./Matrix/Matrix60inv.txt"//加密的可逆矩阵其逆矩阵的位置(60表示其维度)
#define MATRIX_PATH     "./Matrix/Matrix60trans.txt"//加密的可逆矩阵其转置的位置
#define Sk_PATH         "./Sk.txt"//安全kNN加密参数——加密向量的位置
/*注意上述路径要根据自己文件的放置情况进行修改,不然可能会出现“ERROR: GDB exited unexpectedly. Debugging will now abort.“ 
或者“Aborted (core dumped)”的错误*/
// struct of node
typedef struct tree_node {
    int ID; // node ID
    double NSAB[DICT_SIZE]; // index data(非敏感属性关键词布隆过滤器)
    double uSAB[DICT_SIZE];// unecrypted SAB
    double SAB[2][DICT_SIZE]; // index data(敏感属性关键词布隆过滤器)
    struct tree_node *Pl; // pointer to left node
    struct tree_node *Pr; // pointer to right node
    struct tree_node *Pf; // pointer to father node
    int Lid; // pointer to document, use document's label here
} Node;

运行出错的程序del_update_index_tree.cpp如下:

//在索引树上搜索单个不包含敏感属性关键词
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include "define_update.h"

/***
 * This code read the tree from file and do search.
 */

// File data tmp
double B1[FILE_SIZE][DICT_SIZE];//存放从文件中读取的非敏感属性布隆过滤器的值
double B2[FILE_SIZE][DICT_SIZE];//存放从文件中读取的敏感属性布隆过滤器的值,因为涉及后续会涉及加密,故类型定为double
double M[2][DICT_SIZE][DICT_SIZE]={0.0};//存放从文件中读取的加密矩阵
double SAB[2][DICT_SIZE];//暂时存放加密的布隆过滤器以备后续输入到节点的参数中
int Sk[DICT_SIZE]; // encryption vector

// struct of queue
Node queue[FILE_SIZE*2];
int front = 0, rear = -1, itemCount = 0;
Node *insert(Node *data) {
    if( itemCount != FILE_SIZE*2 ) {
        if( rear == FILE_SIZE*2-1 )
            rear = -1;
        queue[++rear] = *data;
        itemCount++;
    }
    return &queue[rear];
}
Node *removeData() {
    Node *data = &queue[front++];
    if( front == FILE_SIZE*2 )
        front = 0;
    itemCount--;
    return data;
}

// read tree from file,注意此部分读入顺序要与生成索引树的参数顺序一样
Node *file2tree( FILE *fp ) {
    if( feof(fp) != 0 ) return NULL;
    int i, l, r, f;
    Node tn;
    // ID 
    fscanf(fp, "%d ", &tn.ID);
    // NSAB
    for( i = 0; i < DICT_SIZE; i++ ) {
        fscanf(fp, "%lf ", &tn.NSAB[i]);
    }
    // SAB
    for( i = 0; i < DICT_SIZE; i++ ) {
        fscanf(fp, "%lf ", &tn.uSAB[i]);
    }
    // pointer
    fscanf(fp, "%d %d %d", &l, &r, &f);
    // Lid
    fscanf(fp, "%d ", &tn.Lid);
    // recursive call
    if( l != -1 )
        tn.Pl = file2tree( fp );
    else
        tn.Pl = NULL;
    if( r != -1 )
        tn.Pr = file2tree( fp );
    else
        tn.Pr = NULL;
    // check left and right child's ID
    if( (tn.Pl != NULL && l != tn.Pl->ID)
            || (tn.Pr != NULL && r != tn.Pr->ID ) ) {
        printf("Error at reading Node %3d from file\n", tn.ID);
    }
    return insert(&tn);
}

void addparent(Node *root,Node *q)
{
    if(root!=NULL)
    {
        root->Pf=q;
        q=root;
        addparent(root->Pl,q);
        addparent(root->Pr,q);
    }
}

// search function
Node *del_node(Node *root, int id) {
    int i;
    if( root->Lid == id ) 
    { // 如果是要删除的节点
        root->ID=-1;
        for( i = 0; i < DICT_SIZE; i++ ) 
        {
            root->NSAB[i] = 0.0;//把布隆过滤器的值传递给节点的参数
            root->uSAB[i] = 0.0;
        }
        root->Pl = NULL;
        root->Pr = NULL;
        root->Lid = -1;
    } 
    else
    {
        del_node(root->Pl, id);
        del_node(root->Pr, id);
    }
    root=root->Pf;
    return root;
}

Node *update_index_tree(Node *root) 
{
    int i,j,k;
    if (root != NULL)
    {
        for( j = 0; j < DICT_SIZE; j++ ) 
        {
            root->NSAB[j] = root->Pl->NSAB[j] + root->Pr->NSAB[j];//把NSAB和uSAB都作为树节点的一个参数
            root->uSAB[j] = root->Pl->uSAB[j] + root->Pr->uSAB[j];
            //此处应该把不同孩子的布隆过滤器直接相加,之后再把其中超过1的值变成1
            if (root->NSAB[j]>1.0)
            {
                root->NSAB[j]=1.0;
            }
            if (root->uSAB[j]>1.0)
            {
                root->uSAB[j]=1.0;
            }
        }
        if (root->Pf!=NULL)
        {
            root=root->Pf;
            update_index_tree(root);
        }
    }
    return root;
}

// write tree to file
void tree2file( FILE *fp, Node *root ) {
    if( root == NULL ) return ;
    int j,k;
    // ID 
    fprintf(fp, "%d ", root->ID);
    // NSAB
    for( j = 0; j < DICT_SIZE; j++ ) {
        fprintf(fp, "%lf ", root->NSAB[j]);
    }
    /* secure kNN encryption */
    for( j = 0; j < DICT_SIZE; j++ ) {
        if( Sk[j] == 0 ) {//依据论文中的规则进行加密
            SAB[0][j] = root->uSAB[j];
            SAB[1][j] = root->uSAB[j];
        } else {
            SAB[0][j] = 0.5*root->uSAB[j] + rand()/RAND_MAX;//rand()/RAND_MAX,产生0到1的随机数
            SAB[1][j] = root->uSAB[j] - SAB[0][j];
        }
    }
    for( j = 0; j < DICT_SIZE; j++ ) {
        root->SAB[0][j] = 0;//初始化节点的参数
        root->SAB[1][j] = 0;
        for( k = 0; k < DICT_SIZE; k++ ) {
            root->SAB[0][j] += M[0][j][k] * SAB[0][k];//生成加密的随机向量
            root->SAB[1][j] += M[1][j][k] * SAB[1][k];//二者形成加密的布隆过滤器
        }
    }
    /*************************/
    // SAB
    for( j = 0; j < DICT_SIZE; j++ ) {
        fprintf(fp, "%lf ", root->SAB[0][j]);//把节点参数写入树文件(后续就不用存储参数uSAB了)
        fprintf(fp, "%lf ", root->SAB[1][j]);//仅保留加密的两个随机向量
    }
    // pointer
    if( root->Pl == NULL )
        fprintf(fp, "-1 ");
    else
        fprintf(fp, "%d ", root->Pl->ID);
    if( root->Pr == NULL )
        fprintf(fp, "-1 ");
    else
        fprintf(fp, "%d ", root->Pr->ID);
    if( root->Pf == NULL )
        fprintf(fp, "-1 ");
    else
        fprintf(fp, "%d ", root->Pf->ID);
    // Lid
    fprintf(fp, "%d\n", root->Lid);
    // recursive call
    tree2file(fp, root->Pl);
    tree2file(fp, root->Pr);
    return ;
}

int main( void ) {
    int i, j, k;
    FILE *fp;
    Node *root, *q;
    Node *Root;
    int id=5;

    //srand( time(NULL) );
    // generate encryption vector and save to file(仅运行一次即可)
    //fp = fopen(Sk_PATH, "w");
    //for( j = 0; j < DICT_SIZE; j++ ) {
        //Sk[j] = rand()%2;
        //fprintf(fp, "%d ", Sk[j]);
    //}
    //fclose(fp);
    // read the encryption vector from the Sk.txt
    fp = fopen(Sk_PATH, "r");
    for( j = 0; j < DICT_SIZE; j++ ) {
        fscanf(fp, "%d ", &Sk[j]);
    }

    // read Matrixs(指矩阵的转置) from file
    fp = fopen(MATRIX_PATH, "r");
    for( k = 0; k < 2; k++ ) {
        for( i = 0; i < DICT_SIZE; i++ ) {
            for( j = 0; j < DICT_SIZE; j++ ) {
                fscanf(fp, "%lf ", &M[k][i][j]);
            }
        }
    }
    fclose(fp);

    struct timeval starttime, endtime;
    double t = 0; //计算时间
    
    gettimeofday(&starttime, NULL);

    // read tree from file
    fp = fopen("./Updatetree500.txt", "r");//手动修改要搜索的树
    root = file2tree(fp);
    addparent(root,q);
    fclose(fp);
    puts("\n\n*** Finish reading the tree with father pointer from file. ***\n\n");

    Root=update_index_tree(del_node(root, id));

    puts("\n\n*** Finish update the index tree. ***\n\n");

    // write tree to file
    fp = fopen("UpdatedEtree500.txt", "w");//可以每次改文件名,EtreeX.txt
    tree2file(fp, Root);
    fclose(fp);

    gettimeofday(&endtime, NULL);

    t = 1000 * (endtime.tv_sec - starttime.tv_sec) + (endtime.tv_usec - starttime.tv_usec)/1000; //ms
    printf("the times of search is:%d:%lf",FILE_SIZE,t);//显示搜索的规模和搜索时间
    printf("ms\n");
    return 0;
}

  • 写回答

3条回答 默认 最新

  • fuill 2022-12-23 12:58
    关注
    
    if(root!=NULL&&root->Lid==id)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 1月1日
  • 已采纳回答 12月24日
  • 创建了问题 12月21日

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效