c - 链表崩溃,c

标签 c linked-list

我的链接列表有问题。我很确定这是我的指针关闭了,或者我没有以正确的方式传递指针,因为我是 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。我试图首先按最短的时间顺序排列列表。

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 %i\n", new_process.processName, new_process.arrivalTime, new_process.timeNeeded, new_process.priority);
        current = current->next;
    }

    return 0;
}

程序在打印时崩溃,这不是问题所在。第一个问题是我的程序每次都会进入 if(head==NULL) 循环并在那里插入。所以 head 可能永远不会改变,但我不知道如何解决这个问题,我很确定它是一个双指针,但不是积极的。我也确信还有其他问题,所以如果你能指出我正确的方向,如果我做了任何完全错误的事情,请告诉我。

编辑:好的,所以在将指针添加到 head 之后,我在 head->next = NULL 处收到错误,提示“表达式必须具有指向类类型的指针”。尝试在 head 之前添加 * 但似乎没有帮助。有谁知道如何解决吗?

最佳答案

您的 add_process 函数在这里:

void add_process(struct process new_process, 
                 struct process *head, 
                 struct process *current)

采用按值传递给它的任何指针。这意味着在 while 循环中调用之后:

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的进程。使用 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
    }
}

完成后不要忘记释放分配的内存。这最好在进程清理函数中完成——相当于 C++ 中的析构函数,只是您必须手动调用它。

关于c - 链表崩溃,c,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7962203/

相关文章:

c - 使用值而不是指针作为函数参数

c - 带有 NULL 指针的基本 printf 行为

一个列表的 C++ 性能

java - 可迭代是如何工作的?

c - 结构效率

c++ - 遍历所有链表的高效算法(C++)

c - Prims算法

c - 如何在不使用数组的情况下计算排序整数的模式

algorithm - 合并两个排序的链表

objective-c - 从函数内的循环返回数字列表