c - 消失的弦

标签 c string malloc strdup

这是我在这里发表的第一篇文章,因此我提前感谢大家的帮助。

我遇到信息消失的问题。该程序应该从文件中读取书名和图书馆 ID 号,创建一个链表哈希表,其中每个节点包含一个书籍结构,该结构保存书名,以及另一个包含书籍可以存储的图书馆 ID 的链表。被发现。此时我只是想填充哈希表,但由于某种原因我的标题值正在消失。文件格式如下所示:

2345,老人与海
567434,哈利·波特
1233,学习的艺术
等等...

我有

typedef NodeStruct {void* data; NodePtr prev; NodePtr next;} NodeStruct;

typedef NodeStruct* NodePtr;

typedef ListStruct {NodePtr first; NodePtr last; NodePtr current; } ListStruct;

typedef ListStruct* ListHndl;

typedef BookStruct {char* title; ListHndl lib; } BookStruct;

typedef BookStruct* BookHndl;

FILE *fileptr;
int numlines;
int numslots;
int i;
int index;
NodePtr fillnode;


int main(int argc, char *argv[]) {
    fileptr = fopen(argv[1], "r");

    if (!fileptr) {
        printf("Error: cannot open file\n");
        return 1;
    }
    int *libID = malloc(sizeof(int));
    printf("(main) libID: %p\n", libID);
    fscanf(fileptr, "%d %d", &numlines, &numslots);
    printf("(main) numlines: %d   numslots: %d\n", numlines, numslots);
    ListHndl *H = calloc(numslots, sizeof(ListHndl));
    printf("(main) calloc iterated\n");

    for (i = 0; i < numlines; i++) {
        printf("*************LOOP #%d*************\n", i);
        char *title = malloc(sizeof(char) * 50);
        if (fscanf(fileptr, "%d%*c%*c%[^\n]", libID, title) == 0) {
            printf("Error: incorrect # of keys\n");
            return 1;
        }
        printf("(main) book: %s  ID: %d\n", title, *libID); 
        index = hash(title, numslots);
        printf("(main) index: %d\n", index);
        printf("(main) hash[index]: %p\n", H[index]);
        if (H[index] == NULL) {
            H[index] = newList();
            printf("(main_if_H_NULL) hash[index]: %p\n", H[index]);
            BookHndl B = newBook(title, libID);
            printf("(main_if_H_NULL) BookHndl B: %p\n", B);
            insertAtFront(H[index],(void *) B);
            printf("(main_if_H_NULL) H[index] title: %s  ID: %d\n", ((BookHndl) H[index]->first->data)->title, 
                        *((int *) ((BookHndl) H[index]->first->data)->lib->first->data));
        }
        printAll(H, numslots);
        NodePtr S = searchTitle(H[index], title);
        printf("(main) NodePtr S: %p\n", S);
        if (S == NULL) {
            BookHndl B = newBook(title, libID);
            insertAtBack(H[index], (void *) B);
            printf("(main_if_!S) inserted book\n");
        } else {
            printf("(main_if_S)\n");
            ListHndl idL = ((BookHndl) S->data)->lib;
            if (searchID(idL, libID) == 0) {
                insertAtBack(idL, (void *) libID);
                printf("(main_if_S) inserted libID\n");
            }
        }
        free((char *) title);
        free((NodePtr) S);
        printAll(H, numslots);
        printf("hash[%d]: %s in library # %d\n", index, title, *libID);
    }

    return 1;
}

实际上有四个 fscanf 参数 %d 用于 libID,%*c 用于跳过“,”,另一个 %*c 用于跳过“”,以及 %[^/n] 用于读取标题,直到出现换行符读。不久后的打印语句确认了 libID 和标题中的正确值。在 printAll(H, numslots) 中,所有值都存在,在返回 NodePtr S = searchTitle(H[index], title) 时,标题消失了。以下是我的 newBook 和 searchTitle 函数

BookHndl newBook(char* str, int* ID) {
    BookHndl B = malloc(sizeof(BookStruct));
    /*B->title = malloc(sizeof(char) * 50);*/
    B->title = strdup(str);
    printf("(newBook) B->title = %s\n", B->title);
    B->lib = newList();
    printf("(newBook) B->lib = %p\n", B->lib);
    insertAtFront(B->lib, (void *) ID);
    printf("(newBook) B->lib->first = %d\n", *((int *)B->lib->first->data));

    return B;
}

NodePtr searchTitle(ListHndl L, char* key) {
    assert(L != NULL);
    if (isEmpty(L)) {
        printf("Book list empty\n");
        return NULL;
    } else {
        L->current = L->first;
        printf("(searchTitle) ListHndl L = %p, L->first = %p, L->first->data = %p\n", L, L->first, (BookHndl) L->first->data);
        while (L->current != NULL) {
            BookHndl B = malloc(sizeof(BookStruct));
            B = (BookHndl) L->current->data;
            printf("(searchTitle) bookhandle B = %p\n", B);
            printf("(searchTitle) B->title = %s\n B->ID = %d\n", B->title, *((int *) B->lib->first->data));
            if (strcmp(B->title, key) == 0) {
                free(B);
                return L->current;
            }
            free(B);
            L->current = L->current->next;
        }
    }
    return NULL;
}

最佳答案

此代码已损坏。

BookHndl B = malloc(sizeof(BookStruct));
B = (BookHndl) L->current->data;
// ...
free(B);

这将泄漏一 block 内存,然后从节点结构中释放一些内容。解决这个问题,问题可能就会消失。

关于c - 消失的弦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23854766/

相关文章:

java - 为什么会出现这些重复案例?

python - 如何通过一些技巧更快地完成这项任务?

python - 字符串比较的时间复杂度

C Keil 编译器使用 malloc 作为局部变量,为什么?

c++ - 将 C 编译的静态库链接到 C++ 程序

c - GTK+ 2.0 C 奇怪的结构和 g_signal_connect_swapped

c - 警告 语言 C : assignment makes pointer from integer without a cast

c++ - 带有尾随注释的多行预处理器宏

c++ - 在 C++ 中分配和释放一个 char *

c - 运行时错误: *** glibc detected ***