C:变量未链接到链表

时间:2016-07-12 12:59:16

标签: c function pointers linked-list pass-by-value

我对C比较陌生,我正在创建一个涉及链表的程序。这是一个非常简短的代码版本,它给我带来了麻烦。

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

#define STRLEN 100

struct Gene { 
    int num[4];
    struct Gene *next;
    };
typedef struct Gene item;

void build_list(item *current, item *head, FILE *in);

int main() {

    FILE *input;
    FILE *output;
    input = fopen("test.data", "r");
    output = fopen("test.out", "w+");

    item *curr;
    item *head; 
    head = NULL;
    int i;

    build_list(curr, head, input);
    curr = head;

    while(curr) {
        for (i = 0; i < 4; ++i)
            fprintf(output, "%d\n", curr->num[i]);
        curr = curr->next;
        }

    fclose(input);
    fclose(output);
    free(curr);
}

void build_list(item *current, item *head, FILE *in) {

    char gene[STRLEN];
    char *tok;
    char gene_name[STRLEN];
    char *search = ",";
    int j;

    while (fgets(gene, sizeof(gene), in)) {

        current = (item *)malloc(sizeof(item));
        tok = strtok(gene, search);
        strcpy(gene_name, tok);
        for (j = 0; j < 4; ++j) {
            tok = strtok(NULL, search);
            current->num[j] = atoi(tok);
            }
        current->next = head;
        head = current;
    }
}

当我尝试编译它时,它表示变量curr未初始化,但即使我用malloc初始化它也会引发分段错误,或者根本不打印任何内容。为什么会这样?

2 个答案:

答案 0 :(得分:2)

C使用pass by值进行函数参数传递。因此,当您致电build_list(curr, head, input);时,currhead本身会按值传递,对这些变量(相应参数)所做的任何更改都不会反映给调用者。

所以,在来电者中,

 while(curr)

正在访问调用undefined behavior的单元化变量(meeory)。

如果您需要自行更改currhead,则需要传递他们的地址并在功能内部进行更改。像

这样的东西
 build_list(&curr, &head, input);

void build_list(item **current, item **head, FILE *in)

*current = malloc(sizeof(item));

可能会为你完成工作。

答案 1 :(得分:0)

@Sourav Ghosh已经解释了你的代码出了什么问题,并提出了一种方法来解决它。这是另一种方式。

我建议您使用函数返回值,而不是将currenthead作为要在函数内部更改的变量(即指针指针)。这样你就不必使用指向指针。

类似的东西:

item* add_item(item* head)
{
    // Place a new item in front
    item* current = malloc(sizeof(item));
    current->next = head;
    return current;
}

item* build_list(item* head, FILE *in) {

    char gene[STRLEN];
    char *tok;
    char gene_name[STRLEN];
    char *search = ",";
    int j;

    while (fgets(gene, sizeof(gene), in))
    {
        // Get a new item
        head = add_item(head);

        // Fill data into the new item
        tok = strtok(gene, search);
        strcpy(gene_name, tok);
        for (j = 0; j < 4; ++j)
        {
            tok = strtok(NULL, search);
            head->num[j] = atoi(tok);
        }
    }

    return head;
}

并从main称之为:

head = NULL;
head = build_list(head, input);

注意:为了便于阅读,我跳过了所有检查失败的malloc。在实际代码中,您应该始终检查malloc是否返回NULL。