1

我正在研究 C 中的链表实现,以掌握指针和结构的窍门。这是我的 LL 数据结构的基本代码:

struct Node {
    void *data;
    struct Node *next;
};

struct List {
    struct Node *head;
};

void initList(struct List *list) {
    list->head = 0;
}

struct Node *addFront(struct List *list, void *data) {
    struct Node *newNode;
    newNode->data = data;
    newNode->next = list->head;
    list->head = newNode;
    return newNode;
}

这是我在int main()函数中对其运行的测试:

int main() {
    /* test addFront */
    double *data1;
    double *data2;
    *data1 = 10.5;
    *data2 = 10.7;
    struct List *newList;
    initList(newList);
    addFront(newList, data1);
    printf("%s\n", newList->head->data);
    addFront(newList, data2);
    printf("%s\n", newList->head->data);

    return 0;
}

我的问题是 printf 没有打印输出。就目前而言,它显然不会打印,因为 %s 与双精度数据类型不匹配。如果我将字符串格式更改为 %d,则会出现分段错误。如果我添加一个(双)强制转换,它表示第二个参数的类型为 double *,这让我感到困惑,因为我认为该->符号取消引用了一个指针。

我迷路了。

4

4 回答 4

3

您没有为double指针data1data2.

看起来,实际上,您几乎没有为任何指针分配内存。

指针本身所做的只是引用内存中的地址。它不分配支持引用的结构或变量所需的内存。

如果你有

double *data1; // or any other kind of pointer

你需要类似的东西

data1 = (double *) malloc(sizeof(double));

那么你可以取消引用所有你喜欢的,例如

*data1 = 12.34;

但是没有那个,你引用了一个指向加尔各答黑洞的指针。

于 2013-02-27T21:29:35.430 回答
3

您正在取消引用data1并且data2没有为它们分配内存。尝试:

double data1 = 10.5;

addFront(newList, &data1);

或者,您可以执行 a malloc,尽管在这种情况下我认为您不应该这样做。

此外,当您想打印它们时,请尝试:

printf("%f\n", *(double *)newList->head->data);
于 2013-02-27T21:24:09.363 回答
1

你做了什么来试图解决这个问题?

尝试使用“assert.h”来确保您的断言是正确的,或者使用 puts/exit 的 if 语句。

特别是,如果它不打印某些东西,很明显你正在打印的不是你想要打印的,所以在某个地方,一个断言肯定会失败,你的大脑会“点击”你错过了一步的地方。

我不能立即这样做的原因是因为我不是你,而且我不知道你在做什么断言,所以我需要比你更长的时间来放置它们。

此外,如上所述,您没有为 newNode 分配内存,也没有访问任意内存,这会导致分段错误。

我在那里修好了。

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

struct Node {
    void *data;
    struct Node *next;
};

struct List {
    struct Node *head;
};

void initList(struct List **newList)
{
    struct List* tmpList = 0;

    assert(newList != 0);
    tmpList = (struct List*)malloc(sizeof(struct List*));
    assert(tmpList != 0);
    tmpList->head = 0;
    *newList = tmpList;
}

void addFront(struct List* list, void* data)
{
    struct Node* currNode = 0;
    struct Node* prevNode = 0;

    assert(list != 0);
    assert(data != 0);

    currNode = list->head;
    while (currNode != 0) {
        prevNode = currNode;        
        currNode = currNode->next;
    }
    if (prevNode == 0) {
        list->head = (struct Node*)malloc(sizeof(struct Node));
        list->head->data = data;
        list->head->next = 0;
    } else {
        prevNode->next = (struct Node*)malloc(sizeof(struct Node));
        prevNode->next->data = data;
        prevNode->next->next = 0;
    }
}

void test(const struct List *list)
{
    const struct Node *iter;
    assert(list != 0);
    assert(list->head != 0);
    iter = list->head;

    while (iter != 0) {
        assert(iter->data != 0);
        printf("%f\n", *((double*)iter->data));
        iter = iter->next;
    }   
}

int main()
{
    double* data1 = (double*)malloc(sizeof(double));
    double* data2 = (double*)malloc(sizeof(double));
    *data1 = 10.5;
    *data2 = 10.7;
    struct List* newList = 0;

    initList(&newList);
    assert(newList->head == 0);
    puts("pass[0].");

    addFront(newList, data1);
    assert(newList->head != 0);
    assert(newList->head->data == data1);
    puts("pass[1].");

    addFront(newList, data2);
    assert(newList->head != 0);
    assert(newList->head->data == data1);
    assert(newList->head->next != 0);
    assert(newList->head->next->data == data2);
    puts("pass[2].");

    test(newList);

    return 0;
}
于 2013-02-27T21:28:21.727 回答
1

除了 2 之外,printf("%f")还缺少4 个malloc:

我用以下标记了更改的行###

#include "stdlib.h"
#include "stdio.h"
struct Node {
    void *data;
    struct Node *next;
};

struct List {
    struct Node *head;
};

void initList(struct List *list) {
    list->head = 0;
}

struct Node *addFront(struct List *list, void *data) {
    struct Node *newNode = malloc(sizeof(struct Node)); //###
    newNode->data = data;
    newNode->next = list->head;
    list->head = newNode;
    return newNode;
}
int main() {
    /* test addFront */
    double *data1 = malloc(sizeof(double)); //###
    double *data2 = malloc(sizeof(double)); //###
    *data1 = 10.5;
    *data2 = 10.7;
    struct List *newList = malloc(sizeof(struct List)); //###
    initList(newList);
    addFront(newList, data1);
    printf("%f\n", *(double*)newList->head->data);//###
    addFront(newList, data2);
    printf("%f\n", *(double*)newList->head->data);//###
    // TODO: free()'s //###
    return 0;
}
于 2013-02-27T21:33:48.100 回答