我正在尝试读取一个包含以下内容的文件。
59878, Moby Dick
442419, The Peach
535, Moby Dick
12, History of War
我有一个包含整数类型的链表,还有一个包含字符和链表指针。这是后一个链表中的一个节点:
typedef struct Node {
struct Node* prev;
char *title;
ListRef library; //Pointer to a different linked list
struct Node* next;
} Node;
typedef struct Node* NodeRef;
NodeRef newNode(char *bookTitle, List LL) {
NodeRef node = (Node*)malloc(sizeof(Node));
node->next = node->prev = NULL;
node->title = (char*)calloc(60, sizeof(char));
node->library = newList();
node->library = LL;
node->title = bookTitle;
return(node);
}
您应该使用存储title
node->title = strdup(bookTitle);
删除calloc
行,因为strdup
将为您分配内存。
当代码当前写入时,您为字符串分配内存,但随后行
node->title = bookTitle;
将指针更改为,使其指向bookTitle
所指向的缓冲区。假定您正在重用bookTitle
缓冲区,因此在程序结束时,所有标题都指向同一缓冲区,并且该缓冲区包含从文件中读取的最后一个标题。
NodeRef newNode(char *bookTitle, List LL) {
NodeRef node = (Node*)malloc(sizeof(Node));
仅供参考:上面的行不需要强制转换malloc((返回的值。相反,行可以是:NodeRef node = malloc(sizeof(Node));
node->next = node->prev = NULL;
node->title = (char*)calloc(60, sizeof(char));
现在node->title指向一个分配的60字节的块。
node->library = newList();
node->library = LL;
node->title = bookTitle;
所以,booktitle是一个指向内存的指针,其中包含一个字符串。上面的语句导致node->title指向bookTitle所指向的同一个东西。对于它之前指向的60个字符的分配块来说太糟糕了;这种记忆现在已成为无法挽回的孤儿。(我敢肯定,这不是我们想要的(。
上面的行应该改为如下内容:
// Assumption: bookTitle contains a properly terminated C string.
node->title = strdup(bookTitle);
if(NULL == node->title)
{
fprintf(stderr, "strdup() failed!n");
/* and handle the error, even though you may never actually see it... */
...
}
return(node);
}
当创建新节点时,它们都指向同一项,即"bookTitle"中包含的地址。因此,当打印出清单时,这就是(危险的(你得到的。所有节点都指向了上一本添加的书的书名。