我的链表有问题。我很确定是我的指针断了,或者我没有以正确的方式传递指针,因为我是c的新手。结构对我来说也是新的,c++是我习惯的语言,有比我意识到的更多的差异。我可以用c++很快完成这个程序,但无论如何,这是我的代码。
void add_process(struct process new_process, struct process *head, struct process *current){
new_process.next = NULL;
if(head == NULL){
head = &new_process;
current = head;
head->next = NULL;
}
else if(new_process.timeNeeded < head->timeNeeded){
temp = head->next;
head = &new_process;
new_process.next = temp;
}
else{
current = head;
while(new_process.timeNeeded > current->timeNeeded){
temp = current;
current = current->next;
}
temp->next = &new_process;
new_process.next = current;
}
}
我正在将文件中的值读取到进程中,我当前使用的唯一一个值是timeNeeded,它是一个int。我试图首先按最短的时间Needed对列表进行排序。
int main(){
FILE *readfile;
readfile = fopen("data.txt","r");
head = NULL;
current = NULL;
while(fscanf(readfile, "%s %i %i %i",
&new_process.processName, &new_process.arrivalTime,
&new_process.timeNeeded, &new_process.priority) != EOF) {
add_process(new_process, head, current);
}
current = head;
while(current->next != NULL){
printf("%s %i %i %in", new_process.processName, new_process.arrivalTime, new_process.timeNeeded, new_process.priority);
current = current->next;
}
return 0;
}
程序在打印时崩溃,这不是问题所在。第一个问题是,我的程序每次都进入if(head==NULL(循环并插入其中。所以头可能永远不会改变,但我不确定如何解决这个问题,我很确定这是一个双指针,但不是积极的。我也确信还有其他问题,所以如果你能给我指明正确的方向,如果我做错了什么,请告诉我。
编辑:好的,所以在添加指向head的指针后,我在head->next=NULL处得到一个错误,说"表达式必须有指向类类型的指针。"尝试在head之前添加一个*,但似乎没有帮助。有人知道怎么修吗?
此处的add_process函数:
void add_process(struct process new_process,
struct process *head,
struct process *current)
按值接受您传递给它的任何指针。这意味着在你的通话后,在这里循环:
while(fscanf(readfile, "%s %i %i %i",
&new_process.processName, &new_process.arrivalTime,
&new_process.timeNeeded, &new_process.priority) != EOF)
{
add_process(new_process, head, current);
}
head仍将为NULL,因为它从未更改过。要让它真正改变头部指针而不是其他指针,请修改您的add_process以采用双层指针:
void add_process(struct process new_process,
struct process **head,
struct process *current)
上面代码的另一个问题是new_process
参数也由值获取。因此,这是您传入的任何进程的临时副本。一旦add_process
返回,new_process
就会超出作用域。现在,这意味着您的链表中有一个悬空指针指向无效内存。
要解决此问题,您应该使用malloc动态分配内存,然后创建new_process的副本。然后让您的链表指向malloc
’ed进程。使用malloc在堆上创建的对象将一直存在,直到释放为止。
这里有一个快速的例子给你一个想法:
typedef struct process Process;
void add_process(Process new_process, Process **head, Process *current)
{
Process *new_proc_copy = (Process *)malloc( sizeof(Process) );
// now copy over the stuff from
// new_process over to this one
memcpy((char *)new_proc_copy, (char *)new_proc, sizeof(Process));
if(*head == NULL)
{
*head = new_process_copy;
current = *head;
(*head)->next = NULL;
}
else if(new_process.timeNeeded < head->timeNeeded)
{
// handle this case
}
else
{
// handle rest of your stuff
}
}
完成后不要忘记释放malloc的内存。这最好在进程清理函数中完成——C++中的析构函数等价物——只需要手动调用它。
为了能够更改head
中包含的值,必须将指向head
的指针传递给add_process
函数。
似乎没有为new_process分配空间。不能每次都使用相同的内存--必须分配一些内存。
还要记住,C不会通过引用自动将参数更改为。因此,如果你想更改某个内容,你必须传递一个指向该内容的指针。这包括其他指针——所以您可能需要一个指向指针的指针。