代码之家  ›  专栏  ›  技术社区  ›  Henry Williams

C-赋值后访问struct属性导致分段错误

  •  0
  • Henry Williams  · 技术社区  · 7 年前

    我有两个结构:wires和wireLLN(导线的链表节点)。其思想是,findWire()函数在链表中查找具有与给定导线同名导线(wireName)的节点。添加第一条导线时,这不会出现任何问题,因为头部节点为null,因此将使用导线作为节点的“导线”属性创建一个新节点。addNode中的printf调用显示了这一点。但是,在第二次运行findWire()时,尝试访问head节点的“wire”属性会导致分段错误。(我已经对代码中出现segfault的位置进行了注释)

    typedef struct wires {
      bool value;
      char* name;
    } Wire;
    
    typedef struct wireLLN {
      Wire wire;
      struct wireLLN * nextNode;
    } WireLLN;
    
    //head of the linked list
    WireLLN * headWire = NULL;
    
    // adds a node to the linked list
    void addNode(WireLLN* head, WireLLN* node){
      if (headWire == NULL){
        headWire = node;
            printf("Head node was null. Adding node with wire name: %s\n", headWire->wire.name); //this prints no problem
        }
      else if (head->nextNode == NULL)
        head->nextNode = node;
      else
        addNode(head->nextNode, node);
    }
    
    //finds if a wire with a given name already exists, if not returns null
    Wire * findWire(char wireName[], WireLLN * head){
      if (headWire != NULL){
            puts("head wasnt null");
            printf("HEAD NODE ADDRESS: %s\n", head);
            printf("HEAD WIRE: %s\n", head->wire); //SEG FAULT HERE
        if (strcmp(head->wire.name, wireName) == 0){
                puts("1");
                return &head->wire;
            } else if (head->nextNode == NULL){
                puts("2");
                return NULL;
            } else {
                puts("3");
                return findWire(wireName, head->nextNode);
            }
      } else return NULL;
    }
    
    
    // assigns a wire to a gate if it exists, otherwise creates a new one then assigns it
    Wire assignWire(char wireName[]){
      Wire * result = findWire(wireName, headWire);
      if (result == NULL){
        Wire wire = makeWire(wireName);
        WireLLN node;
        node.wire = wire;
        addNode(headWire, &node);
        return wire;
      } else {
        return *result;
      }
    }
    

    谢谢你的时间。

    1 回复  |  直到 7 年前
        1
  •  0
  •   GRASBOCK    7 年前

    内存释放问题。Yoiu忘记了一旦函数停止运行,内存将被删除。 这在assignwire函数中发生。

    您可能希望将其更改为:

    Wire assignWire(char wireName[]){
      Wire * result = findWire(wireName, headWire);
      if (result == NULL){
        //to prevent the data being lost after the function returns
        WireLLN* node = (WireLLN*)malloc(sizeof(WireLLN));
        node->wire = makeWire(wireName);
        addNode(headWire, node);
        return node->wire;
      } else {
        return *result;
      }
    }
    

    空检查没有警告您的原因是,您给addNode的指针在函数返回后停止分配内存。 然后您访问该内存(地址相同),但它不是允许您写入任何内容的内存。