正确地返回指针

时间:2018-03-21 10:22:03

标签: c pointers

我在C中创建了一个ADT。它基本上是一个链表。列表中的每个节点都有一个存储项目的成员变量。

void *item

我有一个成员函数,用于添加到列表和删除以及其他。

在我的main.c文件中,我调用ListAdd()函数,它接受一个列表并将一个项添加到下一个可用节点。 ListFirst()函数转到列表的前面并返回存储在该节点的项目。

return list->item

我的主要功能是将一个名为pcb的结构存储为每个节点的项目。 所以这是我的问题。当我在返回void *项之前测试ADT ListFirst()函数时,它具有该项的所有正确成员数据。但在我的main.c文件中,所有信息都不正确。有谁知道为什么会发生这种情况?

我认为因为该项目是无效的*我将地址返回给该项目。所以在我的main.c文件中,代码如下所示:

typdef struct PCB{
        //member variables 
}pcb;

pcb *readypcb;
readypcb = (pcb *)ListFirst(listHead);
//print out data

所以我认为readypcb指针指向ListFirst()返回项的地址。我还将返回值转换为(pcb *),因为我返回void *

因此,作为摘要,我返回void *项之前的行正确打印出项目成员数据。然后在它被分配给readypcb之后我再次打印出数据,只是这一次都是不正确的。有谁知道发生了什么事?

以下是您要求的一些额外代码:

我的PCB数据结构的头文件:

typedef enum Priority{

    high,
    medium,
    low

}Priority;

typedef enum State{

    running,
    ready,
    blocked
}State;

typedef struct PCB{

    Priority priority;              //records the priority level of the PCB
    int pid;                    //The process id of the control block
    State state;                    //records the state of the PCB

    char received[200];             //records any messads sent to this PCB
    char replied[200];              //records the messages that another process replies with

}pcb;

然后我的main.c文件,我分配了返回的项目:

int checkForReadyProcesses(listPtr highP, listPtr medP, listPtr lowP, pcb *readypcb){
    int retCode = 0;

    //check that the item counts for the ready queues are 0
    if(highP->itemCount > 0){
         readypcb = (pcb *)ListFirst(highP);
        //ListRemove(highP);

        if(TESTING_READY_QUEUES){
            printf("We have a PCB in the high priority queue\n");
        }

    }else if(medP->itemCount > 0){
        readypcb = (pcb *)ListFirst(medP);
        //ListRemove(medP);

        if(TESTING_READY_QUEUES){
            printf("We have a PCB in the medium priority queue\n");
        }

    }else if(lowP->itemCount > 0){
        readypcb = (pcb *)ListFirst(lowP);
        //ListRemove(lowP);

        if(TESTING_READY_QUEUES){
            printf("We have a PCB in the low priority queue\n");
        }

    }else{
        retCode = 1;
    }

    if(TESTING_READYPCB){
        printf("The ready address is: %p\n", readypcb);
        printf("The ready state is: %d\n", readypcb->state);
        printf("The ready priority is: %d\n", readypcb->priority);
        printf("The ready id is: %d\n", readypcb->pid);
    }

    return retCode;

}

最后是LstFirst():

void *ListFirst(LIST *list){
    void *tempItem;

    list->currentItem = list->firstNode->item;
    list->currentNode = list->firstNode;

    //updates the position
    list->position = first;

    tempItem = ((list->firstNode->item));

    pcb curpcb = *(pcb *)list->firstNode->item;

    printf("the item has the adress: %p\n", list->firstNode->item);
    printf("the item pid is: %d\n", curpcb.pid);
    printf("the item state is: %d\n", curpcb.state);
    printf("the item priority is: %d\n", curpcb.priority);

    return list->firstNode->item;
}

List.h文件:

typedef struct NODE *nodePtr;
typedef struct List *listPtr;

//define the node structire used for each node in the list except the head node
typedef struct NODE{    
    nodePtr nextNode;       //points to the next node in the list
    nodePtr previousNode;       //points to the previous node in the list
    void *item;         //holds the item for the node
} node;

//define the head structure for the List
typedef struct List{

    nodePtr firstNode;      //points to the first node of the list
    int itemCount;          //holds the number of items in the list
    nodePtr end;            //points to the end of the list
    void *currentItem;      //points to the current item
    nodePtr currentNode;        //points to the current node
    listPtr freedHeadNode;      //used for pointing to freedHead nodes when more than one is available

    //using an enum to represent where the current node is
    enum currentPos{
        beyondEnd = 2,
        end = 1,
        middle = 0,
        beforeStart = -1,
        first = -2,     //this represents the first item ever to be added
    } position;
} LIST;

//FUNCTIONS
LIST *ListCreate();         //creates a new list when called
int ListCount(LIST *list);      //returns the number of items in the list
void *ListFirst(LIST *list);        //returns the first item in the list
void *ListLast(LIST *list);     //returns a pointer to the last item
int ListAdd(LIST *list, void *item);    //adds an item to a list
void *ListCurr(LIST *list);     //points to the current item in the list
void *ListNext(LIST *list);     //points to the next item after the current spot
void *ListPrev(LIST *list);     //points to the previous item before the current node
int ListInsert(LIST *list, void *item); //inserts a node just before the previous node
int ListPrepend(LIST *list, void *item);//adds an item to the begining of the list
int ListAppend(LIST *list, void *item); //adds an item to the end of the list
void *ListRemove(LIST *list);       //removes and returns the current item from the list
void *ListTrim(LIST *list);     //returns and removes the last item of the list
void *ListSearch(LIST *list, int(*comparator)(void *, int), int comparatorArg);
void ListFree(LIST *list, void(itemFree)(void *));

我认为这应该有所帮助。如果您需要任何其他信息,请与我们联系。

1 个答案:

答案 0 :(得分:0)

虽然我没有看到你的所有声明,但很可能你传递了listhead,头部得到了更新,但是无法返回。它无法返回的原因是因为你没有传递“双指针”。考虑:

void example(list *head) {
    if (head==NULL) head= malloc(sizeof(list));
    //...

此处您将内存分配给head,但head本地变量;调用者无法看到对它的任何更改。相反,做:

void example(list **head) {
    if (*head==NULL) *head= malloc(sizeof(list));
    //...

并打电话:

list *myList;
example(&myList);