我试图迭代地为链接列表释放内存。该列表有一个看起来像这样的结构,在这个链表中,如果它在这个列表中,我不会添加一个url。
struct Node {
char *url;
struct Node *next;
};
一旦完成了这个链接列表,我试图释放它,但是得到了分段错误,我仍然在学习c
的方式,我还没有太多线索如何调试这样的错误而不是直接搜索相关主题。引用了一些SO this one,this one和this one,仍然无法弄清楚崩溃的位置。
这是我的代码。如果你想到我在这个实现中错过了什么,可以自由添加评论。
void url_push(struct Node *head, const char *url, size_t url_size) {
struct Node *new_node = (struct Node *) malloc(sizeof(struct Node));
new_node->url = malloc(url_size);
new_node->next = NULL;
for (int i = 0; i < url_size; i++)
*(new_node->url + i) = *(url + i);
struct Node *current = head;
while(1) {
if (strcmp(current->url, new_node->url) == 0) {
printf("Seen page %s!!!!!\n", new_node->url);
free(new_node);
break;
} else if (current->next == NULL) {
current->next = new_node;
break;
} else {
current = current->next;
}
}
}
int main() {
struct Node *head = (struct Node*)malloc(sizeof(struct Node));
head->url = "/";
head->next = NULL;
char *url = "www.google.com";
url_push(head, url, strlen(url));
url = "www.yahoo.com";
url_push(head, url, strlen(url));
url = "www.google.com";
url_push(head, url, strlen(url));
url = "www.wsj.com";
url_push(head, url, strlen(url));
struct Node *current = NULL;
while ((current = head) != NULL) {
printf("url: %s\n", head->url);
head = head->next;
free(current->url);
free(current);
}
}
编辑:
为了减少混淆,我修改了结构。使用strcmp
的目的是避免添加已经看过的网址。
答案 0 :(得分:2)
head->url = "/";
这不是malloced数据所以你不能释放它!
你的另一个问题是在url_push()
new_node->url = malloc(url_size);
,它没有为字符串中的终止0分配足够的空间(也没有复制终止0,所以最终不会“踩踏内存”但确实有未终止的字符串...)。请改为new_node->url = strdup(url);
。
明智的格式:在url_size
中计算url_push()
,而不是让每个来电者strlen()
在被调用的函数内进行一次调用(注意如果你使用strdup()
那么你就不要根本不需要url_size
。
最后的注意事项:像valgrind这样的工具可以轻松找到这两个问题。
答案 1 :(得分:1)
您的代码中存在多个问题:
new_node->url
中的url_push
字符串的空终止符分配空间,导致strcmp()
也有未定义的行为。url
指针。您应该使url_push()
更通用:它应该通过返回新的head
指针来处理空列表。您不需要传递url
字符串的长度,只需使用strdup()
,并且应该在检查重复项之前避免分配新节点。
以下是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
char *url;
struct Node *next;
};
struct Node *url_push(struct Node *head, const char *url) {
struct Node *current = head;
if (current != NULL) {
for (;;) {
if (strcmp(current->url, url) == 0) {
printf("Seen page %s before!!!!!\n", url);
return head;
} else if (current->next == NULL) {
break;
} else {
current = current->next;
}
}
}
struct Node *new_node = malloc(sizeof(struct Node));
if (new_node == NULL || (new_node->url = strdup(url)) == NULL) {
fprintf(stderr, "memory allocation failure\n");
exit(1);
}
new_node->next = NULL;
if (current == NULL) {
head = new_node;
} else {
current->next = new_node;
}
return head;
}
int main() {
struct Node *head = NULL;
head = url_push(head, "/");
head = url_push(head, "www.google.com");
head = url_push(head, "www.yahoo.com");
head = url_push(head, "www.google.com");
head = url_push(head, "www.wsj.com");
while (head != NULL) {
printf("url: %s\n", head->url);
struct Node *current = head;
head = head->next;
free(current->url);
free(current);
}
return 0;
}