如何停止创建 linked 列表的循环以再创建一个空列表 link?
how to stop cycle that creates a linked list to create one more empty link?
struct data {
int date;
int temperature;
char day[11];
struct data *next;
};
typedef struct data Data;
int from_file_to_list(File *fp, Data **list) {
Data *p;
int cnt = 0;
*list = p;
p = malloc(sizeof(Data));
while (fscanf(fp, "%d" "%s" "%d", &(p->date), p->day, &(p->temperature)) == 3) {
p->next = malloc(sizeof(Data));
p = p->next;
cnt++;
}
return cnt;
}
我有这个函数,它用文本文件的数据创建一个 linked 列表,它 returns 列表中 link 的数量,它工作正常,但它在最后为额外的空 link 分配内存,有什么办法可以阻止它吗?因为如果我有一个在最后添加 link 的函数,可能会有问题吧?
初学者似乎有错字
int from_file_to_list(File *fp, Data **list) {
^^^^
应该有
int from_file_to_list(FILE *fp, Data **list) {
^^^^
I have this function that creates a linked list with the data of a
text file and it returns the number of links in the list and it works
fine,
你错了。该函数具有未定义的行为。在这个声明中
int from_file_to_list(File *fp, Data **list) {
Data *p;
int cnt = 0;
*list = p;
//..
您将未初始化的指针 p
分配给了指针 *list
。也就是说,在退出函数后,main 中的指针 list
将具有这个不确定的值。
例如至少可以通过以下方式定义函数
#include <stdlib.h>
#include <string.h>
//...
size_t from_file_to_list( FILE *fp, Data **list )
{
size_t cnt = 0;
int date;
int temperature;
char day[11];
while ( fscanf( fp, "%d" "%s" "%d", &date, day, &temperature ) == 3 &&
( *list = malloc( sizeof( Data ) ) ) != NULL )
{
( *list )->date = date;
( *list )->temperature = temperature;
strcpy( ( *list )->day, day );
( *list )->next = NULL;
list = &( *list )->next;
++cnt;
}
return cnt;
}
或者甚至在从文件创建新列表之前释放列表会更好
size_t from_file_to_list( FILE *fp, Data **list )
{
while ( *list )
{
Data *tmp = *list;
*list = ( *list )->next;
free( tmp );
}
size_t cnt = 0;
int date;
int temperature;
char day[11];
while ( fscanf( fp, "%d" "%s" "%d", &date, day, &temperature ) == 3 &&
( *list = malloc( sizeof( Data ) ) ) != NULL )
{
( *list )->date = date;
( *list )->temperature = temperature;
strcpy( ( *list )->day, day );
( *list )->next = NULL;
list = &( *list )->next;
++cnt;
}
return cnt;
}
如果您将编写一个单独的函数来清除列表,例如
void clear( Data **list )
{
while ( *list )
{
Data *tmp = *list;
*list = ( *list )->next;
free( tmp );
}
}
那么上面的函数可以这样写
size_t from_file_to_list( FILE *fp, Data **list )
{
clear ( list );
size_t cnt = 0;
int date;
int temperature;
char day[11];
while ( fscanf( fp, "%d" "%s" "%d", &date, day, &temperature ) == 3 &&
( *list = malloc( sizeof( Data ) ) ) != NULL )
{
( *list )->date = date;
( *list )->temperature = temperature;
strcpy( ( *list )->day, day );
( *list )->next = NULL;
list = &( *list )->next;
++cnt;
}
return cnt;
}
你设置 *list = p;
before p
设置,所以你有 UB(未定义的行为)。
修复该问题后,您的代码将无法正确处理空列表。
最好将值读入 temp
变量并仅在存在有效数据行时执行 malloc
。
不要对 下一个 记录执行 malloc
。在文件的最后一行,你有一个 extra struct
分配。
这是一些重构代码。是有注释的。我已经编译但没有测试它:
#include <stdio.h>
#include <stdlib.h>
struct data {
int date;
int temperature;
char day[11];
struct data *next;
};
typedef struct data Data;
int
from_file_to_list(FILE *fp, Data **list)
{
Data temp;
Data *prev;
Data *cur;
int cnt = 0;
// make the list empty
*list = NULL;
prev = NULL;
// loop on all lines/records in the file
while (fscanf(fp, "%d" "%s" "%d",
&temp.date, temp.day, &temp.temperature) == 3) {
// allocate new record
cur = malloc(sizeof(*cur));
// copy in the data we just read
*cur = temp;
// append to non-empty list
if (prev != NULL)
prev->next = cur;
// the first record
else
*list = cur;
// remember the previous record
prev = cur;
// advance the count of number of records
cnt++;
}
return cnt;
}
struct data {
int date;
int temperature;
char day[11];
struct data *next;
};
typedef struct data Data;
int from_file_to_list(File *fp, Data **list) {
Data *p;
int cnt = 0;
*list = p;
p = malloc(sizeof(Data));
while (fscanf(fp, "%d" "%s" "%d", &(p->date), p->day, &(p->temperature)) == 3) {
p->next = malloc(sizeof(Data));
p = p->next;
cnt++;
}
return cnt;
}
我有这个函数,它用文本文件的数据创建一个 linked 列表,它 returns 列表中 link 的数量,它工作正常,但它在最后为额外的空 link 分配内存,有什么办法可以阻止它吗?因为如果我有一个在最后添加 link 的函数,可能会有问题吧?
初学者似乎有错字
int from_file_to_list(File *fp, Data **list) {
^^^^
应该有
int from_file_to_list(FILE *fp, Data **list) {
^^^^
I have this function that creates a linked list with the data of a text file and it returns the number of links in the list and it works fine,
你错了。该函数具有未定义的行为。在这个声明中
int from_file_to_list(File *fp, Data **list) {
Data *p;
int cnt = 0;
*list = p;
//..
您将未初始化的指针 p
分配给了指针 *list
。也就是说,在退出函数后,main 中的指针 list
将具有这个不确定的值。
例如至少可以通过以下方式定义函数
#include <stdlib.h>
#include <string.h>
//...
size_t from_file_to_list( FILE *fp, Data **list )
{
size_t cnt = 0;
int date;
int temperature;
char day[11];
while ( fscanf( fp, "%d" "%s" "%d", &date, day, &temperature ) == 3 &&
( *list = malloc( sizeof( Data ) ) ) != NULL )
{
( *list )->date = date;
( *list )->temperature = temperature;
strcpy( ( *list )->day, day );
( *list )->next = NULL;
list = &( *list )->next;
++cnt;
}
return cnt;
}
或者甚至在从文件创建新列表之前释放列表会更好
size_t from_file_to_list( FILE *fp, Data **list )
{
while ( *list )
{
Data *tmp = *list;
*list = ( *list )->next;
free( tmp );
}
size_t cnt = 0;
int date;
int temperature;
char day[11];
while ( fscanf( fp, "%d" "%s" "%d", &date, day, &temperature ) == 3 &&
( *list = malloc( sizeof( Data ) ) ) != NULL )
{
( *list )->date = date;
( *list )->temperature = temperature;
strcpy( ( *list )->day, day );
( *list )->next = NULL;
list = &( *list )->next;
++cnt;
}
return cnt;
}
如果您将编写一个单独的函数来清除列表,例如
void clear( Data **list )
{
while ( *list )
{
Data *tmp = *list;
*list = ( *list )->next;
free( tmp );
}
}
那么上面的函数可以这样写
size_t from_file_to_list( FILE *fp, Data **list )
{
clear ( list );
size_t cnt = 0;
int date;
int temperature;
char day[11];
while ( fscanf( fp, "%d" "%s" "%d", &date, day, &temperature ) == 3 &&
( *list = malloc( sizeof( Data ) ) ) != NULL )
{
( *list )->date = date;
( *list )->temperature = temperature;
strcpy( ( *list )->day, day );
( *list )->next = NULL;
list = &( *list )->next;
++cnt;
}
return cnt;
}
你设置 *list = p;
before p
设置,所以你有 UB(未定义的行为)。
修复该问题后,您的代码将无法正确处理空列表。
最好将值读入 temp
变量并仅在存在有效数据行时执行 malloc
。
不要对 下一个 记录执行 malloc
。在文件的最后一行,你有一个 extra struct
分配。
这是一些重构代码。是有注释的。我已经编译但没有测试它:
#include <stdio.h>
#include <stdlib.h>
struct data {
int date;
int temperature;
char day[11];
struct data *next;
};
typedef struct data Data;
int
from_file_to_list(FILE *fp, Data **list)
{
Data temp;
Data *prev;
Data *cur;
int cnt = 0;
// make the list empty
*list = NULL;
prev = NULL;
// loop on all lines/records in the file
while (fscanf(fp, "%d" "%s" "%d",
&temp.date, temp.day, &temp.temperature) == 3) {
// allocate new record
cur = malloc(sizeof(*cur));
// copy in the data we just read
*cur = temp;
// append to non-empty list
if (prev != NULL)
prev->next = cur;
// the first record
else
*list = cur;
// remember the previous record
prev = cur;
// advance the count of number of records
cnt++;
}
return cnt;
}