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

更新指针值会影响此前赋值吗?指针与动态链表技术问询

问题分析与解决:链表节点复用导致的指针错误

让我来帮你拆解一下这个问题——你遇到的核心问题是重复使用了同一个tmp_edge指针实例,没有为每次循环的新边节点分配独立内存,最终导致链表构建逻辑完全偏离预期。

为什么会出现这个问题?

咱们看你的代码:你只在循环外面执行了一次tmp_edge = malloc(sizeof(graph_edge_t)),之后的每一轮循环,你都是在修改这个同一个节点的内容,然后把last_edge指向它。

举个具体的执行流程:

  1. 第一次循环:给tmp_edge的adjac_vertex_p赋值为2,tmp_edge->next_edge_p = last_edge(此时last_edge是NULL),接着把last_edge指向tmp_edge。
  2. 第二次循环:直接覆盖tmp_edge->adjac_vertex_p的值为3,然后执行tmp_edge->next_edge_p = last_edge——但此时last_edge已经指向了这个唯一的tmp_edge节点,相当于让这个节点的next_edge_p指向了自己!
  3. 后续循环重复这个逻辑,所有的“节点”其实都是同一个内存地址的实例,所以打印时last_edge和tmp_edge的内容完全一致,自然输出不符合预期。

怎么解决?

核心思路是:每次循环都要为新的graph_edge_t节点分配独立的内存,不能复用同一个指针。修改后的代码如下:

#include <stdio.h>
#include <stdlib.h>
/* Structure used to hold a graph vertex information. */
typedef struct graph_vertex {
    int identifier;
    struct graph_vertex *next_vertex_p;
    struct graph_edge *edge_list_p;
} graph_vertex_t;
/* Structure used to hold a graph edge information. */
typedef struct graph_edge {
    struct graph_vertex *adjac_vertex_p;
    struct graph_edge *next_edge_p;
} graph_edge_t;
int main (int argc, char *argv[]) {
    graph_edge_t *tmp_edge = NULL;
    graph_edge_t *last_edge = NULL;
    int id_conn[4] = {2,3,4,5};
    
    for (int i = 0; i < 4; i++) {
        // 关键修改:每次循环创建全新的边节点
        tmp_edge = (graph_edge_t *)malloc(sizeof(graph_edge_t));
        printf("%d ", id_conn[i]);
        
        tmp_edge->adjac_vertex_p = malloc(sizeof(graph_vertex_t));
        tmp_edge->adjac_vertex_p->identifier = id_conn[i];
        tmp_edge->next_edge_p = last_edge; // 此时last_edge是上一轮的节点,初始为NULL
        
        if(tmp_edge->next_edge_p != NULL) {
            printf("LE: %d : TMP %d : EDGE: %d \n", 
                   last_edge->adjac_vertex_p->identifier, 
                   tmp_edge->adjac_vertex_p->identifier, 
                   tmp_edge->next_edge_p->adjac_vertex_p->identifier);
        }
        
        last_edge = tmp_edge; // 更新last_edge为当前新节点
    }
    
    // 别忘了释放内存,避免泄漏
    graph_edge_t *temp_free;
    while(last_edge != NULL) {
        temp_free = last_edge;
        free(last_edge->adjac_vertex_p);
        last_edge = last_edge->next_edge_p;
        free(temp_free);
    }
    
    return 0;
}

关键修改点说明

  • 把tmp_edge = malloc(...)移到了循环内部,确保每一轮循环都生成一个独立的graph_edge_t节点,每个节点都有自己的内存空间。
  • 现在执行tmp_edge->next_edge_p = last_edge时,last_edge保存的是上一轮循环创建的节点(第一次循环时是NULL),不会出现自引用的情况。
  • 新增了内存释放逻辑,这是C语言编程里的好习惯,避免程序结束后留下内存泄漏。

预期输出验证

修改后运行代码,你会得到完全符合预期的输出:

2 3 LE: 2 : TMP 3 : EDGE: 3 
4 LE: 3 : TMP 4 : EDGE: 4 
5 LE: 4 : TMP 5 : EDGE: 5 

内容的提问来源于stack exchange,提问作者BRHSM

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 21:52:37