C: 链表变量未初始化
C: Variable is uninitialized for linked list
我是 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
初始化它时它也会抛出一个分段错误,或者它根本不打印任何内容。为什么会这样?
C 使用按值传递函数参数传递。因此,当您调用 build_list(curr, head, input);
时,curr
和 head
本身是按值传递的,对这些变量(相应参数)所做的任何更改都不会反映给调用者。
所以,在调用者中,
while(curr)
正在访问调用 undefined behavior.
的单元化变量 (meeory)
如果你需要自己改变curr
和head
,你需要传递他们的地址并在函数内部进行更改。像
build_list(&curr, &head, input);
和
void build_list(item **current, item **head, FILE *in)
和
*current = malloc(sizeof(item));
可能会为您完成工作。
@Sourav Ghosh 已经解释了您的代码出了什么问题,并提出了一种解决方法。这是另一种方式。
我建议您使用函数 return,而不是将 current
和 head
作为要在函数内部更改的变量(即作为指针到指针)传递价值。这样你就不必使用指针对指针了。
类似于:
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
returned NULL.
我是 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
初始化它时它也会抛出一个分段错误,或者它根本不打印任何内容。为什么会这样?
C 使用按值传递函数参数传递。因此,当您调用 build_list(curr, head, input);
时,curr
和 head
本身是按值传递的,对这些变量(相应参数)所做的任何更改都不会反映给调用者。
所以,在调用者中,
while(curr)
正在访问调用 undefined behavior.
的单元化变量 (meeory)如果你需要自己改变curr
和head
,你需要传递他们的地址并在函数内部进行更改。像
build_list(&curr, &head, input);
和
void build_list(item **current, item **head, FILE *in)
和
*current = malloc(sizeof(item));
可能会为您完成工作。
@Sourav Ghosh 已经解释了您的代码出了什么问题,并提出了一种解决方法。这是另一种方式。
我建议您使用函数 return,而不是将 current
和 head
作为要在函数内部更改的变量(即作为指针到指针)传递价值。这样你就不必使用指针对指针了。
类似于:
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
returned NULL.