我找不到链表的错误(为什么我的头指针在移动?)
I cant find the error of my linked list( why is my head pointer moving?)
我已经尝试了很多次将头指针指向第一个节点。首先(在空列表中)它正确地指向第一个节点。但是在第一次循环之后,head指针指向链接的newnode。其实现在我对我的整个代码也很不确定。
int main(void){
struct library *head = NULL; //set the head pointer to NULL
int option;
printf("Enter the number:");
while((option = getchar())!= 9){
switch(option){
case '1':
{
char title[1000];
char author[1000];
char subject[1000];
printf("Enter title of the book you want to add:");
scanf("%s",title);
printf("Enter author of the book you want to add:");
scanf("%s",author);
printf("Enter subject of the book you want to add:");
scanf("%s",subject);
add_book(title,author,subject,&head);
printf("successful! and head pointer is pointing to %s\n",head->collection.title);
break;
}
}
}
void add_book(char title[],char author[],char subject[], struct library ** head){
struct library *current;
struct library *newnode = malloc(sizeof(struct library));
newnode->collection.title = title;
newnode->collection.author = author;
newnode->collection.subject = subject; // assigning value inside newnode
newnode->num_books = 0;
newnode->next = NULL; // assign NULL value to the end of newnod
//when the head is NULL which means when the list is empty
if(*head == NULL)
{
current = newnode;
*head = current;
return;
}
else
{
current = *head; //assign the first node to current pointer
//find the last node of the list
while(current->next != NULL)
{
current = current->next;
}
current->next = newnode; // link the last node to new node
return;
}
}
这是为此的结构
struct book {
char* title;
char* author;
char* subject;
};
struct library {
struct book collection;
int num_books;
struct library* next;
};
lifetime of char title[1000];
, char author[1000];
, and char subject[1000];
ends when execution reaches the end of the block inside case '1': { /* ... */ }
. Once this happens, the pointers that were assigned in add_book
become dangling pointers - 指向无效内存。
要解决此问题,您必须确保字符串的生命周期与包含它们的结构的生命周期相匹配。这可以通过在结构本身
中分配足够的 space 来完成
struct book {
char title[1000];
/* etc. */
};
或者通过动态分配足够的 space 来复制每个字符串。在任何情况下,您都必须将字符串复制到此内存 (man 3 strcpy
)。
如果它在您的系统上可用,man 3 strdup
会同时执行第二种形式的两个步骤。否则,与strcpy(malloc(strlen(source_string) + 1), source_string);
.
大致相同
另请注意,scanf
说明符 %s
在不使用 字段宽度说明符 时与 dangerous as gets
相同(例如,char buffer[1000]; scanf("%999s", buffer);
), 因为它可能会溢出你的缓冲区。
一个示例程序。一个一个输入字符串,以EOF
CTRL+D (Windows: CTRL+Z, RETURN).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct link {
char *string;
/* alternatively: char string[512]; */
struct link *next;
};
void add_link(struct link **root, const char *string) {
struct link *node = calloc(1, sizeof *node);
node->string = strdup(string);
/* alternatively: strcpy(node->string, string) */
if (*root) {
struct link *tail = *root;
while (tail->next)
tail = tail->next;
tail->next = node;
} else
*root = node;
}
int main(void) {
struct link *head = NULL;
while (1) {
char buffer[512];
if (!fgets(buffer, sizeof buffer, stdin))
break;
/* remove newline */
buffer[strcspn(buffer, "\n")] = '[=11=]';
add_link(&head, buffer);
}
for (struct link *node = head, *next; node; node = next) {
next = node->next;
printf("STRING: %s\n", node->string);
free(node->string);
free(node);
}
}
注意:在实际程序中,您应该始终检查内存分配函数(malloc
、calloc
、strdup
等)的 return 值,因为他们可能会失败。
我已经尝试了很多次将头指针指向第一个节点。首先(在空列表中)它正确地指向第一个节点。但是在第一次循环之后,head指针指向链接的newnode。其实现在我对我的整个代码也很不确定。
int main(void){
struct library *head = NULL; //set the head pointer to NULL
int option;
printf("Enter the number:");
while((option = getchar())!= 9){
switch(option){
case '1':
{
char title[1000];
char author[1000];
char subject[1000];
printf("Enter title of the book you want to add:");
scanf("%s",title);
printf("Enter author of the book you want to add:");
scanf("%s",author);
printf("Enter subject of the book you want to add:");
scanf("%s",subject);
add_book(title,author,subject,&head);
printf("successful! and head pointer is pointing to %s\n",head->collection.title);
break;
}
}
}
void add_book(char title[],char author[],char subject[], struct library ** head){
struct library *current;
struct library *newnode = malloc(sizeof(struct library));
newnode->collection.title = title;
newnode->collection.author = author;
newnode->collection.subject = subject; // assigning value inside newnode
newnode->num_books = 0;
newnode->next = NULL; // assign NULL value to the end of newnod
//when the head is NULL which means when the list is empty
if(*head == NULL)
{
current = newnode;
*head = current;
return;
}
else
{
current = *head; //assign the first node to current pointer
//find the last node of the list
while(current->next != NULL)
{
current = current->next;
}
current->next = newnode; // link the last node to new node
return;
}
}
这是为此的结构
struct book {
char* title;
char* author;
char* subject;
};
struct library {
struct book collection;
int num_books;
struct library* next;
};
lifetime of char title[1000];
, char author[1000];
, and char subject[1000];
ends when execution reaches the end of the block inside case '1': { /* ... */ }
. Once this happens, the pointers that were assigned in add_book
become dangling pointers - 指向无效内存。
要解决此问题,您必须确保字符串的生命周期与包含它们的结构的生命周期相匹配。这可以通过在结构本身
中分配足够的 space 来完成struct book {
char title[1000];
/* etc. */
};
或者通过动态分配足够的 space 来复制每个字符串。在任何情况下,您都必须将字符串复制到此内存 (man 3 strcpy
)。
如果它在您的系统上可用,man 3 strdup
会同时执行第二种形式的两个步骤。否则,与strcpy(malloc(strlen(source_string) + 1), source_string);
.
另请注意,scanf
说明符 %s
在不使用 字段宽度说明符 时与 dangerous as gets
相同(例如,char buffer[1000]; scanf("%999s", buffer);
), 因为它可能会溢出你的缓冲区。
一个示例程序。一个一个输入字符串,以EOF
CTRL+D (Windows: CTRL+Z, RETURN).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct link {
char *string;
/* alternatively: char string[512]; */
struct link *next;
};
void add_link(struct link **root, const char *string) {
struct link *node = calloc(1, sizeof *node);
node->string = strdup(string);
/* alternatively: strcpy(node->string, string) */
if (*root) {
struct link *tail = *root;
while (tail->next)
tail = tail->next;
tail->next = node;
} else
*root = node;
}
int main(void) {
struct link *head = NULL;
while (1) {
char buffer[512];
if (!fgets(buffer, sizeof buffer, stdin))
break;
/* remove newline */
buffer[strcspn(buffer, "\n")] = '[=11=]';
add_link(&head, buffer);
}
for (struct link *node = head, *next; node; node = next) {
next = node->next;
printf("STRING: %s\n", node->string);
free(node->string);
free(node);
}
}
注意:在实际程序中,您应该始终检查内存分配函数(malloc
、calloc
、strdup
等)的 return 值,因为他们可能会失败。