【问题标题】:Infinite loops with a linked list带有链表的无限循环
【发布时间】:2016-03-07 01:09:04
【问题描述】:

我正在开发一个程序,该程序从stdin 输入数字并计算序列的中值并将其打印为float。我目前在函数中遇到无限循环

len(结构节点 *)

在 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吗?

【问题讨论】:

  • 对于while 循环的每次迭代,您都使用相同的tmpNode。每次都需要分配一个新节点。
  • 您需要为添加到列表中的每个元素分配一个新节点。否则,您只能存储一个值,并且您正在创建一个包含单个节点的循环列表。将 malloc 调用移动到循环中。
  • 好的,谢谢!
  • 对了,移到那里。想一想:如果您的列表有 10 个元素,那么您需要调用 malloc 10 次,每个元素一次。
  • @kaylum 要为数据创建缓冲区,您应该为每个元素再调用一次malloc()

标签: c pointers struct linked-list infinite-loop


【解决方案1】:

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

创建新节点并将它们链接到输入循环中。 给所有节点分配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,可能是错的)

【讨论】:

    【解决方案2】:

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

    顺序是否有序?如果不是,你就误算了中位数。

    假设顺序是有序的。

    我不是很明白这句话的用处

    如果(大小/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 开始,您当前的节点也不是第三个而是第一个。

    祝你好运,希望这会有所帮助!!!!

    【讨论】:

    • 哇,我什至没有意识到我忘了对列表进行排序。谢谢!
    • 编辑了一部分,虽然列表是一个数组(愚蠢),如果您需要帮助,请告诉我!
    猜你喜欢
    • 2013-12-01
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 2018-04-04
    • 1970-01-01
    相关资源
    最近更新 更多