【发布时间】:2014-05-15 05:59:18
【问题描述】:
我有一个如下所示的 C 链表:
typedef struct Node {
struct Node *child;
void *value;
} Node;
typedef struct LinkedList {
Node *head;
} LinkedList;
为了测试一切是否正常,我有一个主程序,它逐行读取文件,并将每一行存储在以下节点中。然后,一旦文件到达末尾,我会遍历链表并打印所有行。
但是,当我测试它时,它只打印空行,除了文件中的最后一行,它可以正常打印。此外,尽管所有字符串在存储在节点中之前都经过 malloc 处理,但我得到一个“指针处于空闲状态,但未分配错误”。我在 gdb 中进行了相当广泛的研究,似乎无法弄清楚我做错了什么。也许其他人可以在这里帮助我?这是我的其余代码:
int main(int argc, char **argv) {
if (argc>1) {
FILE *mfile = fopen(argv[1], "r");
if (mfile!=NULL) {
char c;
char *s = (char*) malloc(1);
s[0] = '\0';
LinkedList *lines = (LinkedList*) malloc(sizeof(LinkedList));
while ((c=fgetc(mfile))!=EOF) {
if (c=='\n') {
setNextLine(lines, s);
free(s);
s = (char*) malloc(1);
s[0] = '\0';
}
else s = append(s, c);
}
if (strlen(s)>0) {
setNextLine(lines, s);
free(s);
}
fclose(mfile);
printList(lines);
LLfree(lines);
} else perror("Invalid filepath specified");
} else perror("No input file specified");
return 0;
}
void setNextLine(LinkedList *lines, char *line) {
struct Node **root = &(lines->head);
while (*root!=NULL) root = &((*root)->child);
*root = (Node*) malloc(sizeof(Node));
(*root)->child = NULL;
(*root)->value = line;
}
char *append(char *s, char c) {
int nl = strlen(s)+2;
char *retval = (char*) malloc(nl);
strcpy(retval, s);
retval[nl-2] = c;
retval[nl-1] = '\0';
free(s);
return retval;
}
void printList(LinkedList *lines) {
Node *root = lines->head;
while (root!=NULL) {
char *s = (char*) root->value;
printf("%s \n", s);
root = root->child;
}
}
void LLfree(LinkedList *list) {
if (list->head!=NULL) NodeFree(list->head);
free(list);
return;
}
void NodeFree(Node *head) {
if (head->child!=NULL) NodeFree(head->child);
free(head->value);
free(head);
return;
}
【问题讨论】:
-
与您的问题无关,但对于
append功能,您确实了解realloc? -
可能与您的问题有关,您没有初始化您分配的
LinkedList结构,这意味着head将具有不确定的值(它看起来是随机的)。访问这个未初始化的成员将导致undefined behavior。 -
“指定的文件路径无效”并不是一个特别有启发性的错误消息。试试
perror(argv[1]) -
您可能希望使用 Valgrind (valgrind.org) 等内存检查器运行代码。
标签: c string linked-list malloc free