【问题标题】:Using malloc with structures in a function在函数中使用带有结构的 malloc
【发布时间】:2014-05-03 23:20:03
【问题描述】:

这是我对该函数的说明:这里将一个无符号整数列表大小传递给此函数,您将创建一个大小为列表大小的链接列表。这将通过重复使用 malloc 并调用 setData 将数据初始化到结构平面字段中来执行。每次将流程放入列表时,您都需要将其放入列表中,以便按字段距离(按升序)对列表进行排序。你返回列表的头部

struct plane* list_intialize(unsigned int num)
{
struct plane *ptr,*head;
int i=0;

ptr = (struct plane*) malloc(num * sizeof(struct plane));

for (i = 0; i < num; ++i)
    setData(ptr+i);

return ptr;
}

这开始是一个已经完成的程序中的一个函数骨架......我要完成这个函数,以便它创建一个链接列表。 setData 被赋予了将数据插入结构元素的函数.....我的问题是,在我运行当前函数后,它只返回一个带有信息而不是数量的平面......我使用 setData 错误还是应该我的当前设置工作

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


#ifndef _MY_DEF_
#define _MY_DEF_

enum dir {NE=0, EN, NW, WN, SE, ES, SW, WS};
enum loc {LNE=0,  LNW,LSE,LSW};
struct plane{
short flightCode;
 long xCord;
 long yCord;
double distance;
char direction;
enum dir flightPattern;
enum loc location;
struct plane *nextPlane;
};

#endif


struct plane* sortByDist(struct plane*);
struct plane * radarPrint(struct plane*head);
int checkPlane(struct plane *);
int checkForCollision(struct plane*);
void  setData(struct plane *pLane);

【问题讨论】:

  • 暂时假设head 在这里是出于某种邪恶的原因遗留下来的代码,你使用什么验证来表明你的结果段只有一个结构宽?您的 setData 呼叫看起来正确,可以接收 single struct plane。它在做什么对我们来说仍然是个谜,因为我们看不到您的代码。如果这应该是一个链表,这是错误的方法。如果它是一个动态 array ?这是有道理的。 (And don't cast malloc() in C programs.)。
  • 忽略成语的问题,我认为这里的根本问题是你被要求创建一个 linked list 但你却创建了一个 array。此外,请求的排序没有发生。如果没有看到 struct plane 的定义,我们就没有比这更有帮助的了。
  • 是的,这是我之前尝试过的,当我使用当前函数运行我的程序时,(就像我说它是一个已经完成的程序,具有另一个正确的函数来打印结构)它只显示一个结果
  • 请在您的问题中发布struct plane 的声明。并验证这是否应该是动态数组或链表。
  • 其他函数不相关,因为它们是正确的,我的问题是我创建的这个函数是否正在执行所要求的操作....它是创建一个 num 结构的链接列表还是只存储一个一个

标签: c function malloc structure


【解决方案1】:

您需要通过分配每个节点来分配您的列表。在链接列表 forward 时这样做的一种方法是下面的代码:

struct plane* list_intialize(unsigned int num)
{
    struct plane *head, **pp = &head;

    int i=0;
    for (i=0; i<num; ++i)
    {
        *pp = malloc(sizeof(**pp));
        setData(*pp);
        pp = &(*pp)->nextPlane;
    }
    *pp = NULL;

    return head;
}

工作原理

这使用一个指向指针的指针来始终保存存储 nextPlane 发电机节点地址的位置的地址。它从头指针的地址开始。对于每个新节点,pp 会填充 那个 节点的 nextPlane 成员的地址。完成后,它会保存 last 节点的 nextPlane 指针的地址,并将其设置为 NULL。由head 指向的第一个节点被返回。 (是的,即使您为请求的大小传递了num = 0,这也有效,在这种情况下,您将返回零节点:即NULL)。

注意:不要忘记,释放列表时需要释放每个节点,提取单个节点等。例如删除整个列表:

void list_delete(struct plane **lst)
{

    while (*lst)
    {
        struct node *victim = *lst;
        *lst = victim->nextPlane;
        free(victim);
    }
}

这样调用:

struct plane *lst = list_initialize(N);

// use list.., maybe adding nodes, removing them, changing, etc...

list_delete(&lst);

如何打印您的清单:

void list_print(const struct plane *lst)
{
    while (lst)
    {
        // TODO: print list node pointed to by lst. 
        // Ex: (x,y) coords
        printf("(%d,%d) ",lst->xCord, lst->yCord);

        lst = lst->nextPlane;
    }
    printf("\n");
}

【讨论】:

  • 你所做的是有道理的,但仍然只显示一个结果....是否有一个简单的功能可以打印我们正在填充数据的结构中的内容,以便我可以确保老师没有搞砸显示功能
  • @Kroganite 我也会发布一个如何打印你的列表,但你必须填写实际输出,因为我不知道你在找什么在这方面。
  • 那会很有帮助
【解决方案2】:

您没有设置对象之间的链接。在for 循环中,您需要:

 ptr[i]->nextPlane = ptr[i+1];

在循环结束时,确保最后一个对象指向 NULL。

ptr[i-1] = NULL;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-07
    • 2018-11-05
    • 1970-01-01
    相关资源
    最近更新 更多