我的任务是从单链表中删除一个节点,并将节点的dataPtr指向的结构设置为新值。我创建了一个结构指针来保存弹出节点的数据。有两种情况我想抓住1(这个新指针为空,我想把它设置到弹出的节点2(如果指针不是空的,我想对它做一些操作。
NODE* printer;
printer = (NODE*) malloc(sizeof (NODE)); //dynamically allocate
if(printer==NULL){ //if it has no data
printer= deleteNode(sList); //call deleteNode function which returns popped node from the passed singly linked list
} else if (printer!=NULL && sList->count!=0) { //if it has data
(((PRINTJOB *) printer->dataPtr)->pageNums) -= PAGESPERMINUTE; //decrement the pageNums field by 1 (PAGESPERMINUTE)
if ((((PRINTJOB *) printer->dataPtr)->pageNums) <= 0) { //if the field is less than 0
printer = NULL; //set pointer back to null
}
printf("printers pageNum is: %dn", ((PRINTJOB *) printer->dataPtr)->pageNums);
}
我的编译器在第4行给我一个错误:该值从未使用过它还在我的else-if语句中给了我一个错误:第一个条件总是真的当我也运行这个代码块时,它会使我的程序崩溃。
我的deleteNode函数是:
#include "headers.h"
void* deleteNode(LIST* list){
NODE *toDelete;
toDelete = list->head;
list->head = toDelete->next;
return toDelete;
}
我的节点结构是:
typedef struct node{
void* dataPtr;
struct node* next;
} NODE;
我的任务是从单链表中删除一个节点,并将节点的dataPtr指向的结构设置为一个新值。
但是您只能有条件地移除节点(并且在不太可能实际发生的条件下(。如前所述,如果第一步是删除节点,则删除。那个节点。
我创建了一个结构指针来保存弹出节点的数据。
但你不应该。如果有任何数据可供接收,那是因为包含该数据的节点已经存在,并且deleteNode()
函数将返回一个指向该节点的指针(前提是该函数实际上已被调用(。
有两种情况我想捕捉1(其中这个新指针为空,我想将其设置为弹出的节点
这毫无意义,因为首先创建一个新的单独节点毫无意义。有意义的是检查deleteNode
是否返回空指针,人们认为如果列表为空,它可能会返回空指针(但请参见下文(。
- 如果指针不为空,我想对它进行一些操作
这可能有意义,但在这种情况下没有意义。根据您的描述,您希望对从列表中删除的节点执行操作(前提是该节点实际上已删除(,但您正在处理新分配的、未初始化的节点。
仅根据你对任务本身的描述,听起来你想要更像这样的东西:
NODE* printer = deleteNode(sList);
if (printer != NULL) {
(((PRINTJOB *) printer->dataPtr)->pageNums) -= PAGESPERMINUTE;
if ((((PRINTJOB *) printer->dataPtr)->pageNums) <= 0) {
printer = NULL; //set pointer back to null (?)
}
printf("printers pageNum is: %dn", ((PRINTJOB *) printer->dataPtr)->pageNums);
} // else nothing to do
但是还有其他可能性,这取决于列表的结构和使用方式。
请注意,我从您的原始代码中复制的printer = NULL;
行有问题。如果稍后的代码在进行更多处理之前对printer
执行null检查,并且您希望避免这种情况,那么这可能是有意义的。但是,请注意,如果不能首先对节点进行free()
,则可能会构成内存泄漏。这样看起来很可疑,但有可能节点真的不应该在那里释放。
但是,也要注意,当deleteNode()
函数在空列表上操作时,它可能会中断。在这种情况下,它似乎唯一可以返回的是一个空指针。在这种情况下,list->head
实际上可能就是这样一个指针,但
NODE *toDelete; toDelete = list->head; list->head = toDelete->next;
在评估toDelete->next
时将尝试取消引用该空指针,从而获得未定义的行为。如果事实上,当列表为空时,你可以依赖list->head
为空,那么你会想修改上面的内容,比如:
NODE *toDelete;
toDelete = list->head;
if (toDelete != NULL) {
list->head = toDelete->next;
} // else list->head is already NULL
同样,根据列表的结构和使用方式,还有其他可能性,但我认为以上可能是您想要的。