您好,我正在尝试从文件中读取内容以制作电影链接列表。在读取文件函数结束时,当我尝试释放行指针并关闭文件时,我得到了段错误和核心转储。释放和文件关闭都会引起问题。我很欣赏一些见解。我需要任何图书馆吗? fopen 工作得很好。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct movie {
char *title;
char **languages;
int year;
double rating;
struct movie *next;
};
struct movie *read_file(const char *filename);
struct movie *create_movie(const char *title, const char **languages, int year, double rating);
void append_movie(struct movie *head, struct movie *new_movie);
void free_movie(struct movie *movie);
int main() {
const char *filename = "movies_sample_1.csv";
struct movie *head = read_file(filename);
while (head != NULL) {
struct movie *temp = head;
head = head->next;
free_movie(temp);
}
return 0;
}
struct movie *read_file(const char *filename) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
perror("Error opening file");
exit(1);
}
struct movie *head = NULL;
char *line = NULL;
size_t len = 0;
ssize_t nread;
if ((nread = getline(&line, &len, file)) == -1) {
perror("Error reading header");
exit(1);
}
while ((nread = getline(&line, &len, file)) != -1) {
char *title = strtok_r(line, ",", &line);
char *year_str = strtok_r(NULL, ",", &line);
char *languages_str = strtok_r(NULL, ",", &line);
char *rating_str = strtok_r(NULL, ",", &line);
int year = atoi(year_str);
double rating = atof(rating_str);
const char *languages[10];
int language_count = 0;
char *language = strtok_r(languages_str, ";[]", &languages_str);
while (language != NULL) {
languages[language_count++] = language;
language = strtok_r(NULL, ";[]", &languages_str);
}
languages[language_count] = NULL;
struct movie *new_movie = create_movie(title, languages, year, rating);
if (head == NULL) {
head = new_movie;
} else {
append_movie(head, new_movie);
}
}
// if (line != NULL) {
// free(line);
// }
//fclose(file);
return head;
}
struct movie *create_movie(const char *title, const char **languages, int year, double rating) {
struct movie *new_movie = (struct movie *)malloc(sizeof(struct movie));
if (new_movie == NULL) {
printf("Memory allocation failed");
exit(1);
}
new_movie->title = strdup(title);
if (new_movie->title == NULL) {
printf("Memory allocation failed");
exit(1);
}
new_movie->year = year;
new_movie->rating = rating;
int num_languages = 0;
while (languages[num_languages] != NULL) {
num_languages++;
}
new_movie->languages = (char **)malloc(sizeof(char *) * (num_languages + 1));
if (new_movie->languages == NULL) {
printf("Memory allocation failed");
exit(1);
}
for (int i = 0; i < num_languages; i++) {
new_movie->languages[i] = strdup(languages[i]);
if (new_movie->languages[i] == NULL) {
printf("Memory allocation failed");
exit(1);
}
}
new_movie->languages[num_languages] = NULL;
new_movie->next = NULL;
return new_movie;
}
void append_movie(struct movie *head, struct movie *new_movie) {
struct movie *current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = new_movie;
}
void free_movie(struct movie *movie) {
free(movie->title);
for (int i = 0; movie->languages[i] != NULL; i++) {
free(movie->languages[i]);
}
free(movie->languages);
free(movie);
}
可能还有更多问题,但这里至少有一个......
getline
将为line
分配动态内存。您必须稍后通过调用 free(line)
来释放该内存。为此,您必须确保 line
未更改,即从 line
获取的值 getline
是要传递给 free
的值。
但是,你确实
char *title = strtok_r(line, ",", &line);
char *year_str = strtok_r(NULL, ",", &line);
char *languages_str = strtok_r(NULL, ",", &line);
char *rating_str = strtok_r(NULL, ",", &line);
因此
line
的值可能/将会改变,并且 free(line)
将失败。