【问题标题】:malloc and pointer in a struct结构中的 malloc 和指针
【发布时间】:2013-05-09 03:26:50
【问题描述】:

我有以下 C 代码:

typedef struct DListNode_ {
    void    *data;
    struct DListNode_ *prev;
    struct DListNode_ *next;
} DListNode;


typedef struct DList_ {
    int size;
    DListNode  *tail;
    DListNode  *head;
} DList;

void insert(DList * list, DListNode * element, int data) {
    DListNode * new_element = (DListNode *)malloc(sizeof(DListNode));
    new_element->data = &data;
    if (list->head==NULL) {
        list->head=list->tail=new_element;
        list->size++;
        return;
    }
    if(element == NULL) {
        // handle size==0?
        new_element->next=list->head;
        list->head->prev=new_element;
        list->head=new_element;
        list->size++;
    } else {
        printf("Not yet implemented!\n");
    }
}

void printNodes(DList *list) {
    DListNode * pointer = list->head;
    if (pointer!=NULL) {
        int v= *((int*)pointer->data);
        printf("Node has value: %d\n", v);
        while (pointer->next != NULL) {
            v = *((int*)pointer->data);
            printf("Node has value: %d\n", v);
            pointer=pointer->next;
        }
    }
}

int main(int argc, const char * argv[])
{

    int e0 = 23;
    int e1 = 7;
    int e2 = 11;
    DList *list = (DList *)malloc(sizeof(DList));
    initList(list);
    assert(count(list)==0);
    insert(list, NULL, e0);
    assert(count(list)==1);

    insert(list,NULL, e1);
    assert(count(list)==2);

    insert(list,NULL, e2);
    assert(count(list)==3);
    printNodes(list);

    return 0;
}

我有几个问题:

  1. DListNode * new_element = (DListNode *)malloc(sizeof(DListNode)); 是否也为 the、data、prev、next 指针分配空间,还是我需要在每个指针上手动调用 malloc那些指针?
  2. 当我在每个节点中打印数据指针的内容时,它们都具有 3 值,即使我插入了 23、7 和 11 并将数据指针设置为 int 的地址:* * new_element->data = &data;**.

(C语言入门教材已订购)

编辑:

insert 现在采用指向数据的 void 指针:

// Insert data as the new head
void insert(DList *list, DListNode *element, void *data) {
    DListNode *new_element = malloc(sizeof(DListNode));
    new_element->data = data;
    if (list->head==NULL) {
        list->head=list->tail=new_element;
        list->size++;
        return;
    }
    if(element == NULL) {
        new_element->next=list->head;
        list->head->prev=new_element;
        list->head=new_element;
        list->size++;
    } else {
        printf("Not yet implemented!\n");
    }
}

主要是我做的:

int main(int argc, const char * argv[])
{
    int i0=7;
    int *ip0 = malloc(sizeof(int));
    ip0 = &i0;

    int i1=8;
    int *ip1 = malloc(sizeof(int));
    ip1 = &i1;

    int *ip2 = malloc(sizeof(int));
    int i2=44;
    ip2 = &i2;

    DList *list = malloc(sizeof(DList));
    initList(list);
    // create some nodes
    assert(count(list)==0);
    insert(list, NULL, ip0);
    assert(count(list)==1);

    insert(list,NULL, ip1);
    assert(count(list)==2);

    insert(list,NULL, ip2);
    assert(count(list)==3);
    printNodes(list);

    return 0;
}

哪个输出:

Node has value: 44
Node has value: 44
Node has value: 8

但应该是:

Node has value: 44
Node has value: 8
Node has value: 7

【问题讨论】:

  • 您不需要在 C 程序中强制转换 malloc 的返回值。
  • A DListNode_ 只不过是其字段的总和。除了您提到的指针之外,没有什么可以分配其他

标签: c pointers


【解决方案1】:
  1. malloc(sizeof(DListNode)) 只为一个DListNode 分配空间,根据定义,它由一个void* 和两个DListNode 指针组成。但是,它不会初始化这些指针。

  2. 您将data 参数的地址分配给insert。这是一个指向临时的指针,一旦insert 返回,它就会失效。程序的行为是未定义的。简单的解决方案是将void *data 替换为int data

【讨论】:

  • .. 初始化它们可能不需要调用malloc。事实上,对于正常的链表行为,您可能不会 malloc 他们。
  • @CarlNorum:我不确定你的意思。每当(或:几次)我在 C 中实现链表时,我malloc'd 每个节点,分别,尽管这不是在所有情况下都需要。
  • 我很确定(尽管如果我错了他可以纠正我)OP 正在询问他是否需要在他的程序当前调用初始化指针之后再调用 malloc 三次在他的列表结构中。我只是说他可能不会。
【解决方案2】:
  1. 您需要手动将这些指针设置为使用 malloc 指向的位置。没有它,它们将指向一个不是 DListNode 大小的空间。

  2. 不要将数据设为指针。只需将数据设为 int(它会自动分配),然后只需设置 data = data(传入 insert 的数据)。

【讨论】:

  • malloc 对于普通的列表语义可能不是必要的。只需将它们指向预先存在的节点(如果没有,则指向 NULL)。
  • 是的,只要那里已经有一个节点,你就对了。否则,当您创建节点时,最简单的方法是从下一个指针中分配这些结构。
  • 你为什么要这样做?如果您还没有节点,您希望列表指针全部为NULL,对吗?
  • malloc 一个节点,然后设置指针是一回事,就像从指针中 malloc 空间并在那里放置一个节点结构一样。
  • 好的,我想我明白你的意思了。不过,我认为你会让 OP 感到困惑,而不是帮助他。
猜你喜欢
  • 2016-07-05
  • 1970-01-01
  • 2013-01-23
  • 1970-01-01
  • 2012-06-04
  • 1970-01-01
  • 2021-11-22
  • 2016-07-30
  • 1970-01-01
相关资源
最近更新 更多