全局指针(链表头)未正确更新
Global pointer (head of linked list) not updated properly
我已经搜索了很多,在我问这个之前,但我无法让这段小代码工作。
我知道使用 global pointer
(或变量)被认为是 不好的做法 (而不是通过引用传递)但我不得不遗憾地使用这种做法。
我想做的是制作一个 linked list
,它由节点(struct
和一些信息)组成,并且在每个 insert()
之后,列表动态扩展一个node
(除非相关元素已经存在,否则成员 name
将被覆盖)。
指针 next
指向 list
中的下一个元素(这是我从 malloc()
.
分配新节点的地方
程序编译正确并执行,输出如下:
retrieve returned: (NULL)
每次 printf()
调用
这就是我认为全局指针(列表头)未正确更新的原因
很抱歉提出这个幼稚的问题,但我似乎无法找到 assignment/allocation 哪里出错了,
无论如何提前感谢您的帮助。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node{
char *id;
char *name;
struct node *next;
};
struct node* list; //list head
struct node* p; //pointer to list head
char *retrieve(char *id){
if(list == NULL)
return NULL; //list is empty, no element to return.
for(p = list; p != NULL; p = p->next)
if(strcmp(id, p->id) == 0)
return p->name;
return NULL;
}
void insert(char *id, char *name){
int exists = 0;
struct node* temp = NULL;
for(p = list; p != NULL; p = p->next){
if(strcmp(id, p->id) == 0){ //id already exists, overwrite with the new name.
free(p->name);
p->name = strdup(name);
exists = 1;
break;
}
}
if(exists) return;
//insert at the end of the list
temp = malloc(1 * sizeof(struct node));
if(temp == NULL){
printf("memory allocation failed\n");
return;
}
temp->id = strdup(id);
temp->name = strdup(name);
temp->next = NULL;
p = temp;
return;
}
int main(){
struct node* temp = NULL;
p = NULL;
list = NULL;
insert("145a","Jim");
insert("246b","Alice");
insert("322c","Mike");
printf("retrieve returned: %s\n\n", retrieve("145a"));
printf("retrieve returned: %s\n\n", retrieve("246b"));
printf("retrieve returned: %s\n\n", retrieve("322c"));
p = list;
while(p != NULL){ // node deletion starting from first to last element.
free(p->id);
free(p->name);
temp = p;
p = p->next;
free(temp);
}
return 0;
}
除 NULL
外,您永远不会初始化 list
。结果,
char *retrieve(char *id){
if(list == NULL)
return NULL;
总是returnsNULL
.
void insert(char *id, char *name)
{
struct node *temp = NULL, **pp;
/* Pointer to pointer points to the global */
for(pp = &list; *pp ; pp = &(*pp)->next){
if(strcmp(id, (*pp)->id) ) continue;
free((*pp)->name);
(*pp)->name = strdup(name);
return;
}
//insert at the end of the list
temp = malloc(sizeof *temp);
if(!temp ){
printf("memory allocation failed\n");
return;
}
temp->id = strdup(id);
temp->name = strdup(name);
temp->next = NULL;
*pp = temp;
return;
}
你甚至可以不用 *temp 指针:
void insert(char *id, char *name)
{
struct node **pp;
for(pp = &list; *pp ; pp = &(*pp)->next){
if(strcmp(id, (*pp)->id) ) continue;
free(p->name);
p->name = strdup(name);
return;
}
// pp now points to the terminal NULL pointer
*pp = malloc(sizeof **pp);
if(!*pp ){
printf("memory allocation failed\n");
return;
}
(*pp)->id = strdup(id);
(*pp)->name = strdup(name);
(*pp)->next = NULL;
return;
}
我已经搜索了很多,在我问这个之前,但我无法让这段小代码工作。
我知道使用 global pointer
(或变量)被认为是 不好的做法 (而不是通过引用传递)但我不得不遗憾地使用这种做法。
我想做的是制作一个 linked list
,它由节点(struct
和一些信息)组成,并且在每个 insert()
之后,列表动态扩展一个node
(除非相关元素已经存在,否则成员 name
将被覆盖)。
指针 next
指向 list
中的下一个元素(这是我从 malloc()
.
程序编译正确并执行,输出如下:
retrieve returned: (NULL)
每次 printf()
调用
这就是我认为全局指针(列表头)未正确更新的原因
很抱歉提出这个幼稚的问题,但我似乎无法找到 assignment/allocation 哪里出错了,
无论如何提前感谢您的帮助。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node{
char *id;
char *name;
struct node *next;
};
struct node* list; //list head
struct node* p; //pointer to list head
char *retrieve(char *id){
if(list == NULL)
return NULL; //list is empty, no element to return.
for(p = list; p != NULL; p = p->next)
if(strcmp(id, p->id) == 0)
return p->name;
return NULL;
}
void insert(char *id, char *name){
int exists = 0;
struct node* temp = NULL;
for(p = list; p != NULL; p = p->next){
if(strcmp(id, p->id) == 0){ //id already exists, overwrite with the new name.
free(p->name);
p->name = strdup(name);
exists = 1;
break;
}
}
if(exists) return;
//insert at the end of the list
temp = malloc(1 * sizeof(struct node));
if(temp == NULL){
printf("memory allocation failed\n");
return;
}
temp->id = strdup(id);
temp->name = strdup(name);
temp->next = NULL;
p = temp;
return;
}
int main(){
struct node* temp = NULL;
p = NULL;
list = NULL;
insert("145a","Jim");
insert("246b","Alice");
insert("322c","Mike");
printf("retrieve returned: %s\n\n", retrieve("145a"));
printf("retrieve returned: %s\n\n", retrieve("246b"));
printf("retrieve returned: %s\n\n", retrieve("322c"));
p = list;
while(p != NULL){ // node deletion starting from first to last element.
free(p->id);
free(p->name);
temp = p;
p = p->next;
free(temp);
}
return 0;
}
除 NULL
外,您永远不会初始化 list
。结果,
char *retrieve(char *id){
if(list == NULL)
return NULL;
总是returnsNULL
.
void insert(char *id, char *name)
{
struct node *temp = NULL, **pp;
/* Pointer to pointer points to the global */
for(pp = &list; *pp ; pp = &(*pp)->next){
if(strcmp(id, (*pp)->id) ) continue;
free((*pp)->name);
(*pp)->name = strdup(name);
return;
}
//insert at the end of the list
temp = malloc(sizeof *temp);
if(!temp ){
printf("memory allocation failed\n");
return;
}
temp->id = strdup(id);
temp->name = strdup(name);
temp->next = NULL;
*pp = temp;
return;
}
你甚至可以不用 *temp 指针:
void insert(char *id, char *name)
{
struct node **pp;
for(pp = &list; *pp ; pp = &(*pp)->next){
if(strcmp(id, (*pp)->id) ) continue;
free(p->name);
p->name = strdup(name);
return;
}
// pp now points to the terminal NULL pointer
*pp = malloc(sizeof **pp);
if(!*pp ){
printf("memory allocation failed\n");
return;
}
(*pp)->id = strdup(id);
(*pp)->name = strdup(name);
(*pp)->next = NULL;
return;
}