链接列表:未分配正在释放的指针

时间:2018-11-30 01:13:24

标签: c

我正在研究C中Segdwick的算法,并尝试了链表的动态数组。我在public void setGame(char... input) { this.phrase = input; this.maskedPhrase = new char[input.length]; Arrays.fill(this.maskedPhrase, '*'); } 的{​​{1}}遇到了分段错误。我的重点是正确加载和打印链接列表,完成后我没有释放列表数组。

所以我添加了main函数,现在得到了return 0。显然,我缺少指针/取消引用的细微差别。有什么建议吗?

freeList运行:

pointer being freed was not allocated

运行lldb

a.out(3057,0x7fffb470c380) malloc: *** error for object 0x100300470: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
44Process 3057 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00007fff7c22cb6e libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
->  0x7fff7c22cb6e <+10>: jae    0x7fff7c22cb78            ; <+20>
    0x7fff7c22cb70 <+12>: movq   %rax, %rdi
    0x7fff7c22cb73 <+15>: jmp    0x7fff7c223b00            ; cerror_nocancel
    0x7fff7c22cb78 <+20>: retq
Target 0: (a.out) stopped.

代码:

a.out

1 个答案:

答案 0 :(得分:1)

请勿使用三重星形指针(例如struct node ***adj)。几乎总是保证它们会产生不良/无法读取的结果。有其他更清洁的方法。在这里,双星可能就是您想要的。

正如MFisherKDX所述,进行adj[j] = &t;会将基于堆栈的指针变量t的地址保存到数组中,而不是t 指向的地址。要解决此问题,函数参数 必须使用struct node **adj


这是您的代码的版本。您的原始代码(需要更改)包装如下:

#if 0
// original code
#else
// fixed code
#endif

这是您的固定代码(边注:不要强制转换malloc的返回值)。另外,请注意,原始printf中的freeList会取消引用空指针,因此我修复了该问题[没有#if 0配对]:

#include <stdlib.h>
#include <stdio.h>

#define maxV 13

struct node {
    int v;                              // vertex number
    struct node *next;
};

// load array of linked lists

static void
#if 0
load_adjlist_array(struct node ***adj)
#else
load_adjlist_array(struct node **adj)
#endif
{
    // load adjacency array
    int j,
     x,
     y,
     V,
     E;
    struct node *t;
    int idx[maxV];                      // vertex location on adjacency matrix

    // ALL edges, single way (combinations)
    char v1[maxV] = { 'A', 'A', 'A', 'L', 'J', 'J', 'J', 'E', 'F', 'H', 'F', 'A', 'G' };
    char v2[maxV] = { 'G', 'B', 'C', 'M', 'M', 'L', 'K', 'D', 'D', 'I', 'E', 'F', 'E' };

    V = maxV;                           // number of vertices
    E = maxV;                           // number of edges

    // setup vertex positions in linked list
    for (j = 0; j < V; j++)
        idx[j] = j;
    // setup head for each vertex (vertex connected to NULL by default)
    for (j = 0; j < V; j++) {
        t = (struct node *) malloc(sizeof *t);  // pointer to allocated node memory
        if (t != NULL) {
            t->v = j;
            t->next = NULL;
#if 0
            adj[j] = &t;
#else
            adj[j] = t;
#endif
        }
        else
            return;
    }

    // for each edge ('AB'), update the relevant linked list: add node to head of that vertex's list
    for (j = 0; j < E; j++) {
        // edge xy: vertex numbers (also positions in idx)
        x = idx[v1[j] - 'A'];
        y = idx[v2[j] - 'A'];
        // load x data into t, then add t to y's adj list
        // printf("handling %c\n",v1[j]);
        t = (struct node *) malloc(sizeof *t);
        if (t != NULL) {
            t->v = x;
#if 0
            t->next = *adj[y];
#else
            t->next = adj[y];
#endif
#if 0
            *adj[y] = t;
#else
            adj[y] = t;
#endif
        }
        else
            return;
        // add y to x's adj list
        // printf("handling %c\n",v2[j]);
        t = (struct node *) malloc(sizeof *t);
        if (t != NULL) {
            t->v = y;
#if 0
            t->next = *adj[x];
#else
            t->next = adj[x];
#endif
#if 0
            *adj[x] = t;
#else
            adj[x] = t;
#endif
        }
        else
            return;
    }

    printf("load_adjlist_array completed\n");
}

static void
freeList(struct node *head)
{
    struct node *tmp;

    printf("\n");
    while (head != NULL) {
        tmp = head;
        head = tmp->next;
        printf("%d", tmp->v);
        free(tmp);
    }

}

int
main()
{

    int j;
#if 0
    struct node **adj;                  // pointers to adjacency list
#else
    struct node **adj;                  // pointers to adjacency list
#endif

    adj = malloc(maxV * sizeof(struct node *)); // allocates pointers to linked lists
    if (adj == NULL)
        return -1;

#if 0
    load_adjlist_array(&adj);           // allocates memory to linked lists in adj
#else
    load_adjlist_array(adj);            // allocates memory to linked lists in adj
#endif

    for (j = 0; j < maxV; j++) {
        freeList(adj[j]);
    }
    free(adj);

    return 0;
}

这是一个清理的版本:

#include <stdlib.h>
#include <stdio.h>

#define maxV 13

struct node {
    int v;                              // vertex number
    struct node *next;
};

// load array of linked lists

static void
load_adjlist_array(struct node **adj)
{
    // load adjacency array
    int j,
     x,
     y,
     V,
     E;
    struct node *t;
    int idx[maxV];                      // vertex location on adjacency matrix

    // ALL edges, single way (combinations)
    char v1[maxV] = { 'A', 'A', 'A', 'L', 'J', 'J', 'J', 'E', 'F', 'H', 'F', 'A', 'G' };
    char v2[maxV] = { 'G', 'B', 'C', 'M', 'M', 'L', 'K', 'D', 'D', 'I', 'E', 'F', 'E' };

    V = maxV;                           // number of vertices
    E = maxV;                           // number of edges

    // setup vertex positions in linked list
    for (j = 0; j < V; j++)
        idx[j] = j;
    // setup head for each vertex (vertex connected to NULL by default)
    for (j = 0; j < V; j++) {
        t = malloc(sizeof *t);  // pointer to allocated node memory
        if (t != NULL) {
            t->v = j;
            t->next = NULL;
            adj[j] = t;
        }
        else
            return;
    }

    // for each edge ('AB'), update the relevant linked list: add node to head of that vertex's list
    for (j = 0; j < E; j++) {
        // edge xy: vertex numbers (also positions in idx)
        x = idx[v1[j] - 'A'];
        y = idx[v2[j] - 'A'];
        // load x data into t, then add t to y's adj list
        // printf("handling %c\n",v1[j]);
        t = malloc(sizeof *t);
        if (t != NULL) {
            t->v = x;
            t->next = adj[y];
            adj[y] = t;
        }
        else
            return;
        // add y to x's adj list
        // printf("handling %c\n",v2[j]);
        t = malloc(sizeof *t);
        if (t != NULL) {
            t->v = y;
            t->next = adj[x];
            adj[x] = t;
        }
        else
            return;
    }

    printf("load_adjlist_array completed\n");
}

static void
freeList(struct node *head)
{
    struct node *tmp;

    printf("\n");
    while (head != NULL) {
        tmp = head;
        head = tmp->next;
        printf("%d", tmp->v);
        free(tmp);
    }

}

int
main()
{

    int j;
    struct node **adj;                  // pointers to adjacency list

    // allocates pointers to linked lists
    adj = malloc(maxV * sizeof(struct node *));
    if (adj == NULL)
        return -1;

    load_adjlist_array(adj);            // allocates memory to linked lists in adj

    for (j = 0; j < maxV; j++) {
        freeList(adj[j]);
    }
    free(adj);

    return 0;
}

这是固定程序的输出:

load_adjlist_array completed

52160
01
02
543
6534
0435
406
87
78
1011129
910
91211
91112