c - C 中的 Delete() 函数中的段错误(核心转储)

标签 c linked-list runtime-error nodes

我正在使用 C 中的链表编写字典,除了删除函数之外,我的所有函数都可以工作,如下所示以及所有其他必要的代码。每次我尝试运行我的程序,只要它到达必须删除节点的行,它就会给我错误:段错误(核心转储),这意味着它与内存分配或空指针有关我认为。我知道我的其余代码可以工作。感谢所有和任何帮助! :)

#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);
}

考虑在此场景中使用原始代码(没有 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()内部有效(垃圾在外部,因此在检查( ) - 节点->随机数据的关键点)。

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

相关文章:

c - malloc 运行时错误

c - getaddrinfo 不一致的行为

c - ANN : Learning Vector Quantization not working

c - 链表的具体排序

c - 从链表中释放函数时出错

c - 删除双向链表中的第 n 个节点

flutter - CocoaPods 要求您的终端使用 UTF-8 编码。考虑将以下内容添加到 ~/.profile。导出 LANG=en_US.UTF-8

c# - 如何修复此 Esc 键错误?

mysql - 尝试通过以下方式将 sql 文件导入到远程数据库。程序

c++ - 从 C++ 迁移到 C