代码之家  ›  专栏  ›  技术社区  ›  Daniel Hornik

使用fclose()后损坏的双链接列表;

  •  0
  • Daniel Hornik  · 技术社区  · 9 年前

    我的程序有问题。 使用函数后 fclose() 我出错了:

    " *`中出错/服务器“:损坏的双链接列表:0x00000000251a230* Przerwane(zrzut pamici)“

    如果我删除 f关闭() 功能一切正常。 这是我的功能代码:

    FILE *fHandler;
    struct udp_message **returnArray;
    struct udp_message *message;
    char *line = NULL;
    uint32_t linesNum;
    uint32_t i = 0;
    size_t length; 
    ssize_t read;
    
    fHandler = fopen(filePath, "r");
    if (fHandler == NULL) {
        perror("ERROR");
        return NULL;
    }
    
    returnArray = malloc(sizeof(struct udp_message *)*CONSOLE_BUFFER);
    message = malloc(sizeof(struct udp_message));
    
    while ((read = getline(&line, &length, fHandler)) != -1) {
        message = (struct udp_message *)line;
        if (message->messageTime < aboveTime) {
            continue;
        }
    
        returnArray[i] = malloc(sizeof(struct udp_message));
        memcpy(returnArray[i++], message, sizeof(struct udp_message));
    }
    
    memcpy(messageNum, &i, sizeof(i));
    fclose(fHandler);
    
    return returnArray;
    
    3 回复  |  直到 9 年前
        1
  •  2
  •   ameyCU    9 年前

    查看代码的这一部分-

    message = malloc(sizeof(struct udp_message));       /* <--- 1 */
    
    while ((read = getline(&line, &length, fHandler)) != -1) {
       message = (struct udp_message *)line;            /*  <--- 2.  */
       if (message->messageTime < aboveTime) {
           continue;
       }
    

    您将内存分配给 message (参见要点 1. ),但在 while 使其指向的循环 line (点 2. ).

    因此,您丢失了对先前分配的内存的引用( 这两个指针指向同一个内存位置 ),因此如果您 free 他们会的 自由的 相同的内存导致双重 自由的 相同的内存位置。

    所以,如果你想 消息 指向 线 ,则不将内存分配给 消息 .

        2
  •  0
  •   Konstantin Kulakov    9 年前

    可能值得检查对象是否为空

    if(fHandler != NULL)
        fclose(fHandler);
    
        3
  •  0
  •   chqrlie    9 年前

    你不太可能用 getline 。有可能 while 循环迭代次数超过 CONSOLE_BUFFER 时间和你的写作超过了 returnArray ,破坏堆内部结构。 fclose() 释放与流相关联的缓冲器, free 由于堆损坏而崩溃。

    顺便提一句 memcpy(messageNum, &i, sizeof(i)); 可能不正确。您没有发布函数原型,但应该设置存储在 returnArray返回数组 具有 *messageNum = i; ,特别是如果类型不是 uint32_t * .