Ich schreibe ein bisschen C-Code und versuche, ein bisschen mit Listen zu spielen. Aus irgendeinem Grund bringt der folgende Code mir den Autor, Jahr und ISBN des Buches, aber der Titel fehlt. Ich vermute, dass es irgendwo in der Funktion "insert_at_begin" ein Speicherleck gibt. Obwohl ich mir wirklich nicht sicher bin, was ich dort machen soll. Das Programm liest aus einer Datei mit Buchnamen, Autoren usw. und sollte diese als dynamische Liste zurückgeben.Speicherverlust in einer C-verknüpften Liste
Jeder Hinweis oder irgendeine Art von Hilfe würde sehr geschätzt werden. Ich habe mich im Internet umgesehen und einen Stack-Überlauf gefunden, konnte aber keine Lösung für dieses Speicherleck finden. Ich habe den entsprechenden Code hinzugefügt, obwohl es ziemlich lang ist, ich bin mir nicht sicher, wo das Leck ist, also dachte ich, es wäre besser so.
typedef struct _element element;
typedef struct _list {
element *first;
int count;
} list;
struct _element {
char* title;
char* author;
int year;
long long int isbn;
element *next;
};
element *insert_at_begin(element *first, element *new_elem) {
if(first) {
new_elem->next = first;
first = new_elem;
} else {
first = new_elem;
}
return first;
}
element *construct_element(char *title, char* author, int year, long long int isbn) {
element* book = malloc(sizeof(element));
book->title = title;
book->author = author;
book->year = year;
book->isbn = isbn;
book->next = NULL;
return book;
}
void free_list(list *alist) {
//Only when there is 2 elements in the list start this loops
for (int i=1; i<alist->count; i++) {
free(alist->first->next);
}
free(alist->first);
free(alist);
}
void read_list(char* filename, list *alist) {
element* new_elem;
char* title;
char* author;
int year;
long long int isbn;
read_line_context ctx;
open_file(&ctx, filename);
while(read_line(&ctx, &title, &author, &year, &isbn) == 0) {
new_elem = construct_element(title, author, year, isbn);
alist->first = insert_at_begin(alist->first, new_elem);
alist->count++;
}
}
list* construct_list() {
list *alist = malloc(sizeof(list));
alist->first = NULL;
alist->count = 0;
return alist;
}
void print_list(list *alist) {
printf("My Books\n================\n\n");
int counter = 1;
element *elem = alist->first;
while (elem != NULL) {
printf("Book %d\n", counter);
printf("\tTitel: %s\n", elem->title);
printf("\tAuthor: %s\n", elem->author);
printf("\tYear: %d\n", elem->year);
printf("\tISBN: %lld\n", elem->isbn);
elem = elem->next;
counter++;
}
}
int main(int argc, char** argv) {
list *alist = construct_list();
read_list(argc>1?argv[1]:"buecherliste.txt", alist);
print_list(alist);
free_list(alist);
return 0;
}
Dies ist, was gedruckt wird, wie Sie die Titel sehen können fehlen und einige der Informationen wird immer abgehackt. Ich habe das X-Code-Leaks-Tool versucht, konnte dort aber nichts Nützliches finden. Ich habe eine printf-Funktion zum Debuggen in der while-Schleife von read_list hinzugefügt, und dort funktionierte es perfekt. Also muss es etwas mit der insert_at_begin Funktion sein.
My Books
================
Book 1
Titel:
Author: Phillip K. Dick
Year: 1973
ISBN: 9780547572178
Book 2
Titel:
Author: nner Darkly
Year: 1949
ISBN: 9783548267456
UPDATE: Hier ist die read_line Funktion:
int read_line(read_line_context *ctx, char **name, char **author, int *year, long long int *isbn) {
if (ctx->filepointer == NULL){
perror(ctx->filename);
exit(1);
}
char *name_s;
char *author_s;
char *year_s;
char *isbn_s;
char *delim = ";";
ssize_t len;
if ((len = getline(&(ctx->line), &(ctx->linecapp), ctx->filepointer)) != -1)
{
/* remove tailing newline */
char *pos;
if ((pos = strchr(ctx->line, '\n')) != NULL)
*pos = '\0';
/* read individual fields */
name_s = strtok(ctx->line, delim);
author_s = strtok(NULL, delim);
year_s = strtok(NULL, delim);
isbn_s = strtok(NULL, delim);
if(name_s != NULL && author_s != NULL && year_s != NULL && isbn_s != NULL) {
*name = name_s;
*author = author_s;
*year = atoi(year_s);
*isbn = atoll(isbn_s);
return 0;
}
}
fclose(ctx->filepointer);
ctx->filepointer = NULL;
ctx->linecapp = 0;
if (ctx->line != NULL) {
free(ctx->line);
}
return -1;
}
Verwenden Sie [Valgrind] (http://valgrind.org/). Ihre Schleife innerhalb von 'free_list' sollte wahrscheinlich 'while (ptr)' durchlaufen und sollte mit 'nextptr = ptr-> next enden; frei (ptr); ptr = nextptr; '. Und Sie sollten eine Zeichnung auf Papier oder Karton machen, um die Form Ihrer Datenstrukturen zu verstehen. –
Zeige Teil von 'read_line' – BLUEPIXY
Zeigen Sie uns den Platz, wo Sie den Speicher für die Strings' title' und 'author' reservieren. Ihre Datenstruktur enthält nur Zeiger auf sie - sie müssen auf einen Speicherbereich zeigen, der für die gesamte Lebensdauer der Datenstruktur gültig ist. – tofro