带有链表的无限循环

Infinite loops with a linked list

我正在开发一个程序,该程序从 stdin 中获取数字输入并计算序列的中位数并将其打印为 float。我目前在函数

中遇到无限循环

len(struct node *)

在 for 循环中,我不确定为什么。

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

struct node {
    float *val;
    struct node *next;
};

int len(struct node *list) {
    int i = 0;
    struct node *temp = list;
    for (i = 0; temp != NULL; i++) {
        temp = temp->next;
    }
    return i;
}

float median(int size, struct node list) {
    struct node temp = list;
    int i = 0;
    if (size == 1) {
        return *temp.val;
    } else
    if (size == 2) {
        return (*(temp.val) + *(temp.next->val)) / 2;
    } else {
        if (size / 2 == 1) {
            for (i = 3; i != (size / 2) - 1; i++) {
                temp = *(temp.next);
            }
            return *temp.val;
        } else {
            for (i = 3; i != (size / 2); i++) {
                temp = *(temp.next);
            }
            return (*(temp.val) + *(temp.next->val)) / 2;
        }
    }
}

int main() {
    struct node *tmpnode;
    tmpnode = malloc(sizeof(struct node));
    tmpnode->next = NULL;
    struct node *list = NULL;
    list = tmpnode;
    float temp = 0;
    int err = 0;
    int size = 0;
    while ((err = scanf("%f", &temp)) != EOF) {
        if (err < 1) {
            fprintf(stderr, "Error: non-integer character inputted\n");
            return 1;
        }
        tmpnode->val = &temp;
        tmpnode->next = list;
        list = tmpnode;
    }
    size = len(list);
    if (size == 0) {
        fprintf(stderr, "Error: no inputs found");
        return 1;
    }
    printf("%f\n", median(size, *list));
    return 0;
}

编辑:我已经修复了无限循环,但现在我在 median() 中的 temp = *(temp.next) 处遇到段错误。我需要为 temp 分配吗?

您只创建了一个节点并将该节点的 next 分配给了它自己,因此这是无限循环的原因。

在输入循环中创建新节点并link它们。 将temp的地址分配给所有节点也不好。

你的 main() 函数应该是这样的:

int main(void){
    struct node *tmpnode;
    tmpnode = malloc(sizeof(struct node));
    if(tmpnode == NULL){
        perror("malloc 1");
        return 1;
    }
    tmpnode->next = NULL;
    struct node *list = NULL;
    list = tmpnode;
    float temp = 0;
    int err = 0;
    int size = 0;
    while((err = scanf("%f", &temp)) != EOF){
        if(err < 1){
            fprintf(stderr, "Error: non-integer character inputted\n");
            return 1;
        }
        tmpnode->val = malloc(sizeof(float));
        if(tmpnode->val == NULL){
            perror("malloc 2");
            return 1;
        }
        *tmpnode->val = temp;
        tmpnode->next = malloc(sizeof(struct node));
        if(tmpnode->next == NULL){
            perror("malloc 3");
            return 1;
        }
        tmpnode = tmpnode->next;
        tmpnode->val = NULL;
        tmpnode->next = NULL;
    }
    size = len(list);
    if(size == 0){
        fprintf(stderr, "Error: no inputs found");
        return 1;
    }
    printf("%f\n", median(size, *list));
    /* code to free the list should be here */
    return 0;
}

(我输入了 1 2 3 4 5 而这个程序的输出是 1.500000,这可能是错误的)

如果您正在寻找中位数,则必须按顺序排列节点并获得 middle.If 中的数字点头数是偶数并且没有中间点您应该添加两个最中间的数字并将它们除以二。

顺序对吗?如果不是,那你算错了中位数。

假设顺序正确

我没有真正理解这句话的用处

if(size/2 == 1)

也许您正在尝试查看尺寸是否奇怪。在那种情况下你应该这样做:

>  if(size%2 == 1)

为什么列表可能循环可能是由于这个

 for(i = 3; i != (size/2); i++){
          temp = *(temp.next);
 }

假设你将一个 5 传递给函数 size/2=2(小数部分丢失),那么它会一直继续下去直到发生溢出并且它实际上达到 2,这使得你的程序很可能 seg_fault正在处理中。

从 i=0 开始,因为即使你从 3 开始,你当前的节点不是第三个而是第一个。

祝你好运希望这对你有帮助!!!!