我正在使用C中的链表编写字典,除删除功能外,所有其他功能均正常工作,删除功能与所有其他必要代码一起显示在下方。每当我尝试运行程序时,只要它到达必须删除节点的行,它就会给我以下错误:Segmentation Fault(核心转储),这意味着它与内存分配或空指针有关我认为。我知道其余的代码都可以工作。感谢所有帮助! :)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include"Dictionary.h"

// NodeObj
typedef struct NodeObj{
    char* key;
    char* value;
    struct NodeObj* next;
} NodeObj;

// Node
typedef NodeObj* Node;

// newNode()
// constructor of the Node type
Node newNode(char* key, char* value)
{
    Node N = malloc(sizeof(NodeObj));
    assert(N!=NULL);
    //  if(key!=NULL && value!=NULL){
    N->key = key;
    N->value = value;
    N->next = NULL;
    //  }
    return(N);
}

// DictionaryObj
typedef struct DictionaryObj{
    Node head;
    int numItems;
} DictionaryObj;

// newDictionary()
// constructor for the Dictionary type
Dictionary newDictionary(void){
    Dictionary D = malloc(sizeof(DictionaryObj));
    assert(D!=NULL);
    D->head = NULL;
    D->numItems = 0;
    return D;
}

Node findKey(Dictionary D, char*key){
    Node N;
    N = D->head;
    while(N != NULL){
        if(strcmp(N->key,key)==0){
            return N;
        }
        N = N->next;
    }
    return NULL;
}

char* lookup(Dictionary D, char* k){
    if(findKey(D, k)==NULL){
        return NULL;
    }else{
        Node N;
        N = findKey(D, k);
        return N->value;
    }
}

void delete(Dictionary D, char* k)
{
    if(lookup(D,k) == NULL){
        fprintf(stderr,
                "KeyNotFoundException: Cannot delete non-existent key\n");
        exit(EXIT_FAILURE);
    }
    int check = strcmp(D->head->key, k);
    if(check == 1){
        D->head = D->head->next;
        return;
    }
    Node cur;
    Node prev;
    cur = D->head;
    prev = NULL;

    while( cur != NULL){
        int ret1;
        ret1 = strcmp(cur->key, k);
        while( ret1 == 0){
            prev = cur;
            cur = cur->next;
        }
    }
    prev->next = cur->next;
    D->numItems--;
}

最佳答案

NodeObject应该存储字符串的副本,并小心删除它:

typedef struct Node Node;
struct Node {
    Node *next;
    char *key, *value;
};

Node* newNode(char* key, char* value) {
    assert(key && value);
    Node* node = (Node*)malloc(sizeof(Node));
    assert(node);
    node->next = NULL;
    node->key = strdup(key);
    node->value = strdup(value);
}
void delNode(Node* node) {
    free(node->key);
    free(node->value);
}


考虑在此scenairo中使用原始代码(没有strdup):

Node* prepare() {
    char key_buf[20]; strcpy(key_buf, "mykey");
    char val_buf[20]; strcpy(val_buf, "myval");
    return newNode(key_buf, val_buf);
}
void examine(Node* node) {
   printf("Node key=%s value=%s\n", node->key, node->value);
}
int main() {
    examine(prepare());
}


上面的代码将崩溃,因为Node将有堆栈指针(在您的情况下没有该strdup),但是key_buf + val_buf仅在prepare()内部有效(在外部以及因此在检票内部有效)-node-> key指向随机数据)。

关于c - Delete()函数中C中的段错误(核心已转储),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25051476/

10-11 15:31