我正在使用一些插入函数创建链接列表。
这种方法很好用:
void insert_before(){
struct node *new_node, *ptr, *preptr;
int pivot;
new_node = (struct node*)malloc(sizeof(struct node));
ptr = link;
preptr = link;
printf("\n Enter the data : ");
scanf("%d", &new_node->data);
printf("\n Enter the value before which the data has to be inserted : ");
scanf("%d", &pivot);
while(ptr->data != pivot){
preptr = ptr;
ptr = ptr->next;
}
preptr->next = new_node;
new_node->next = ptr;
}
但是,我在这个方法中得到了Cannot access memory at address 0x8
:
void insert_after(){
struct node *new_node, *ptr, *preptr;
int pivot;
new_node = (struct node*)malloc(sizeof(struct node));
ptr = link;
preptr = link;
printf("\n Enter the data : ");
scanf("%d", &new_node->data);
printf("\n Enter the value after which the data has to be inserted : ");
scanf("%d", &pivot);
while(preptr->data != pivot){
preptr = ptr;
ptr = ptr->next;
}
preptr->next = new_node;
new_node->next = ptr;
}
请注意,这两种方法都使用相同的struct * link
,唯一的区别在于循环while(preptr->data != pivot)
。
为什么第一个代码工作正常,但第二个代码坏了?
感谢您的帮助
PS:这是我的整个项目(非常简短),万一你需要它:https://pastebin.com/wsMEicGv
答案 0 :(得分:3)
我不认为即使是第一种方法也能正常工作(简单证明:代码永远不会改变 $("#Order").data("kendoNumericTextBox").value(data);
的值,因此在第一个节点之前的插入不能工作)。
无论如何,当您为link
输入的值与任何数据不匹配或与列表中的最后一个节点匹配时,您的代码将在这两个函数中产生上述错误消息:
pivot
原因是当条件while(preptr->data != pivot){
preptr = ptr;
ptr = ptr->next;
}
仍然访问此空指针时,上面的循环将到达列表的末尾(具有preptr = NULL
)。我想成员preptr->data
是你结构中的第二个(第一个是data
),对吗?然后,您实际访问的next
(NULL + sizeof(node*))
(NULL + 8)
。
答案 1 :(得分:1)
你有很多不好的做法:
malloc()
。scanf()
或malloc()
等函数的返回值。fflush(stdin);
是未定义的行为。例如,display()
可能如下所示:
void display(struct node *head) { // no global it's better, isn't it ?
printf("List:");
while (head != NULL) {
printf(" %d", head->data);
head = head->next;
}
printf("\n");
}
此外,在您的create_ll()
函数中,为什么不在之后使用插入开始和反转列表?
int create_ll(struct node **head) {
*head = NULL;
while (insert_beginning(head) != ERROR) {
}
return reverse_ll(head);
}
使用示例:
int main(void) {
struct node *head;
if (create_ll(&head) == ERROR) {
return 1;
}
display(head);
free_ll(head);
}
对于两个功能的问题,请阅读stephan-lechner的answer。但我举个例子:
int insert_after(struct node **head) {
printf("\n Enter the data : ");
int data;
if (scanf("%d", &data) != 1) { // If the input has no been parse.
// data is invalid here
return ERROR;
}
// data is valid here
printf("\n Enter the value after which the data has to be inserted : ");
int pivot;
if (scanf("%d", &pivot) != 1) {
return ERROR;
}
for (struct node *node = *head; node != NULL; node = node->next) {
if (node->data == pivot) {
struct node *new_node = malloc(sizeof *new_node);
if (new_node == NULL) {
return ERROR;
}
new_node->data = data;
new_node->next = node->next;
node->next = new_node;
return OK;
}
}
return ERROR;
}
请注意:如果使用全局,则列表功能将为:
更多信息here。