我完全搞不清我在这里做错了什么。我有一个链接的节点列表(请参阅下面的结构),我对如何在修剪列表时释放内存感到困惑我认为将它们添加到数组(eventArr)可以使它们更容易在以后释放,但我仍然有问题有人能帮我指出正确的方向吗?

static void trim_list(int room, int keep, char timestamp[]) {

        struct room_t *the_room;
        struct room_t *the_room_copy;

        struct evnode_t *eventArr[20];
        int index = 0;

        the_room_copy = malloc(sizeof(struct room_t));
        the_room = find_room(room);

        the_room_copy->room = the_room->room;
        the_room_copy->ecount = the_room->ecount;
        the_room_copy->evl_head = the_room->evl_head;

        struct evnode_t *node;

        int counter;
        int removed = 0;

        for(counter = 0; counter != keep; counter++){
          the_room_copy->evl_head = the_room_copy->evl_head->next;
        }

        while(the_room_copy->evl_head){
          eventArr[index] = the_room_copy->evl_head;
          the_room_copy->evl_head = the_room_copy->evl_head->next;
          index++;
          removed++;
        }

        for(index = 0; index < removed; index++){
          free(eventArr[index]);
        }

        printf("Trim log @ %s: room %i log trimmed to length %i (%i entries removed)\n",timestamp, room, keep, removed);

        return ;
}

结构:
struct evnode_t {
        struct event_t event ;
        struct evnode_t *next ;
} ;

struct room_t {
        int room ;
        int ecount ;
        struct evnode_t *evl_head ;
        struct room_t *next_room ;
} ;

struct event_t {
        int sensor ;
        char time_stamp[MAX_TIMESTRING+1];
        int event_id ;
        int event_info ;
} ;

我应该注意到,为了更好地理解它,我在gdb中运行了这个程序,但是由于某些原因,这些值变得一团糟。以下是我的输出:
在运行trim_list之前。。。
(gdb) p room_list->room
$1 = 1
(gdb) p room_list->evl_head->event.sensor
$2 = 9
(gdb) p room_list->evl_head->next->event.sensor
$3 = 4
(gdb) p room_list->evl_head->next->next->event.sensor
$4 = 2
(gdb) p room_list->evl_head->next->next->next->event.sensor
$5 = 2
(gdb) p room_list->evl_head->next->next->next->next->event.sensor
$6 = 3
(gdb) p room_list->evl_head->next->next->next->next->next->event.sensor
$7 = 2

运行trim_list之后。。。
(gdb) p room_list->evl_head->next->event.sensor
$8 = 4
(gdb) p room_list->evl_head->next->next->event.sensor
$9 = 2
(gdb) p room_list->evl_head->next->next->next->event.sensor
$10 = 2
(gdb) p room_list->evl_head->next->next->next->next->event.sensor
$11 = 0
(gdb) p room_list->evl_head->next->next->next->next->next->event.sensor
$12 = 6396880

任何关于我为什么会遇到这些问题的见解都会很有帮助我不确定我是否正确理解如何释放价值观。。。不过,我知道被释放的值都已被malloced。为了澄清,room_list是我试图从中释放值的列表,the_room_copymalloc的新room_listed版本。

最佳答案

看起来您正在正确释放节点你没有做的是在新的位置终止列表例如,如果旧列表是:

1 -> 9 -> 4 -> 2 -> 2 -> 3 -> 2 -> NULL

如果你想在第五个元素之后修剪,你现在所做的事情会变成这样:
1 -> 9 -> 4 -> 2 -> 2 -> (freed memory) -> (unknown pointer) -> ...

您需要做的是在要保留的链接列表之后终止该链接列表:
1 -> 9 -> 4 -> 2 -> 2 -> NULL

下面是一些示例代码,显示了终止列表的一种方法:
    struct evnode_t *end_of_list = NULL;

    // This is your existing loop to skip past "keep" elements.
    for(counter = 0; counter != keep; counter++){
      end_of_list = the_room_copy->evl_head;
      the_room_copy->evl_head = the_room_copy->evl_head->next;
    }

    // Free stuff as you did before...

    // At the very end:
    if (end_of_list == NULL) {
        // Keep nothing.
        the_room->evl_head = NULL;
    } else {
        // Terminate the list at the proper place.
        end_of_list->next = NULL;
    }

    // Oh, you need to free the copy also, it's a memory leak:
    free(the_room_copy);

关于c - 与释放C中的内存混淆吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29724477/

10-17 01:26