在Delete()函数中的C中的分段错误(核心转储)

时间:2014-07-31 05:33:18

标签: c linked-list runtime-error nodes

我正在使用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--;
}

1 个答案:

答案 0 :(得分:0)

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()中有效(外部垃圾,因此在的内部() - 节点 - &gt;关键指向随机数据。)