You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

机械工程C程序中链表函数recherche_noe、creation_noeud引发段错误求助

排查并修复你的机械工程C程序段错误问题

让我们一步步拆解你代码里的核心问题——尤其是recherche_noe和creation_noeud函数的致命缺陷,这些正是触发段错误的主要原因:

1. recherche_noe函数的致命错误

这个函数存在两个严重问题:

  • 类型不匹配:函数声明返回noeuds(即struct noeud*),但你返回的是maillages类型的temp,指针类型混乱直接触发段错误。
  • 破坏原链表:你用temp = mail指向原maillage结构体,然后修改temp->lst_noe = temp->lst_noe->next,这会直接移动原链表的头指针,导致节点丢失,后续访问链表时必然触发空指针访问。

修复后的recherche_noe:

noeuds recherche_noe(maillages mail, int num){
    noeuds temp = mail->lst_noe; // 用noeuds类型指针遍历,不修改原链表
    while(temp != NULL){
        if(temp->num == num)
            return temp;
        temp = temp->next;
    }
    printf("Le noeud recherche n'existe pas\n");
    return NULL; // 找不到返回NULL,避免返回垃圾值
}

2. creation_noeud函数的核心问题

  • 返回类型错误:函数功能是创建节点链表,却定义返回matrices类型,且没有任何return语句,导致栈中垃圾值被返回,引发未定义行为。应改为void类型。
  • 输入处理逻辑缺陷:getchar()的使用会吃掉有效输入,且未初始化节点的u或f,导致后续使用时出现垃圾值。

修复后的creation_noeud:

void creation_noeud(maillages mail){
    int i;
    for (i=0; i<mail->nb_noe; i++){
        noeuds new = (noeuds)malloc(sizeof(struct noeud));
        if(new == NULL){ // 检查malloc是否成功,避免空指针
            perror("Erreur allocation noeud");
            exit(EXIT_FAILURE);
        }
        new->num = i+1;
        new->u = 0.0; // 初始化避免垃圾值
        new->f = 0.0;

        printf("Deplacement du noeud %d (laissez vide pour saisir l'effort): ", i+1);
        while(getchar() != '\n'); // 清除缓冲区残留的换行符
        fgets(buffer, sizeof(buffer), stdin);
        buffer[strcspn(buffer, "\n")] = '\0'; // 去掉换行符

        if(strlen(buffer) > 0){ // 用户输入了位移u
            new->u = atof(buffer);
        } else { // 用户直接回车,输入力f
            printf("Donner l'effort du noeud %d: ", i+1);
            scanf("%lf", &new->f);
        }
        new->next = mail->lst_noe;
        mail->lst_noe = new;
    }
}

3. recherche_elt函数的类似修复

和recherche_noe一样,它破坏了原链表的lst_elt指针,且返回逻辑错误:

修复后的recherche_elt:

elements recherche_elt(maillages mail, int num){
    elements temp = mail->lst_elt;
    while(temp != NULL){
        if(temp->num == num)
            return temp;
        temp = temp->next;
    }
    printf("L'element recherche n'existe pas\n");
    return NULL;
}

4. assemblage函数的错误修复

  • 移除了未初始化i就调用recherche_elt的错误语句
  • 遍历元素时先获取当前元素,避免多次调用recherche_elt破坏链表
  • 增加空指针检查,避免访问无效内存

修复后的assemblage:

void assemblage(maillages mail){
    int a,b,i;
    elements current_elt;
    noeuds current_noe;

    mail->K = creation_mat(mail->nb_noe, mail->nb_noe,"K");
    mail->U = creation_mat(mail->nb_noe, 1,"U");
    mail->F = creation_mat(mail->nb_noe, 1,"F"); // 初始化F矩阵

    // 组装K矩阵
    for (i=0; i<mail->nb_elt; i++){
        current_elt = recherche_elt(mail, i+1);
        if(current_elt == NULL) continue; // 找不到元素则跳过

        a = current_elt->n1 - 1;
        b = current_elt->n2 - 1;
        mail->K->tab[a][a] += current_elt->k;
        mail->K->tab[a][b] -= current_elt->k;
        mail->K->tab[b][a] -= current_elt->k;
        mail->K->tab[b][b] += current_elt->k;
    }

    // 组装U矩阵
    for (i=0; i<mail->nb_noe; i++){
        current_noe = recherche_noe(mail, i+1);
        if(current_noe != NULL){
            mail->U->tab[i][0] = current_noe->u;
        } else {
            mail->U->tab[i][0] = 0.0; // 找不到节点则设为0
        }
    }
}

5. produit函数的补全(避免后续问题)

当前函数未完成,补全矩阵乘法逻辑:

matrices produit(matrices mat1, matrices mat2, char *nom){
    int i,j,k;
    matrices prod = NULL;
    if(mat1->m != mat2->n){
        printf("Erreur, les matrices ne sont pas compatibles\n\n");
        return NULL;
    }else{
        prod = creation_mat(mat1->n, mat2->m, nom);
        if(prod == NULL) return NULL;

        // 执行矩阵乘法
        for(i=0; i<mat1->n; i++){
            for(j=0; j<mat2->m; j++){
                prod->tab[i][j] = 0.0;
                for(k=0; k<mat1->m; k++){
                    prod->tab[i][j] += mat1->tab[i][k] * mat2->tab[k][j];
                }
            }
        }
    }
    return prod;
}

额外注意事项

  • 初始化maillage结构体:在main中创建实例后,要将lst_noe、lst_elt初始化为NULL,nb_noe、nb_elt初始化为0,避免访问未初始化指针。
  • 内存释放:程序结束前记得释放所有malloc分配的内存(节点、元素、矩阵),避免内存泄漏。
  • 输入验证:对用户输入的节点编号、元素的n1/n2等进行范围验证,避免数组越界。

内容的提问来源于stack exchange,提问作者Talal C.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:25:07