1

I have a linked list and I am attempting to insert a new node, which seems to be successful at inserting the node where I want it to go, but the variables keep coming out as NULL. Could someone point to where I am causing this to happen?

Here is the print and insert method.

void printList(node *head)
{
    node *p;
    p = head;
    if(p->next == NULL)
            printf("No stops currently in the tour.");
    else
    {
            while(p->next != NULL)
            {
                    printf("Tour Stop: %s - Description: %s\n", p->name, p->name);
                    p = p->next;
                            }
    }
}


void insertInOrder(node *head, node *newNode)
{
    printf("What is the stop you want the new stop to come after? Type 'end' to insert at the end of the tour.");
    char key[100];
    scanf("%s", &key);
    getchar();

    node *p;
    p = head->next;
    if(head->next == NULL)
            head->next = newNode;

    else if(key == "end")
    {
            while(p->next != NULL)
                    p = p->next;

            p->next = newNode;
    printf("\nAT 57, newNode->info = %s and newNode->name = %s", newNode->info, newNode->name);
    }

    else
    {
            while(strcmp(p->name, key) != 0)
            {
                    if(p->next == NULL)
                    {
                            printf("Couldn't find the tour stop you requested, inserting at end of tour.");
                            break;
                    }

                    p = p->next;
            }

            p->next = newNode;
    }

And here is the createNewNode method I am using to pass into the insert method

node* createNewNode()
{
    node *newNode;
    newNode = malloc(sizeof(struct node));

    printf("Enter the name of the new tour stop.\n");
    char newName[100];
    fgets(newName, sizeof(newName), stdin);
    newNode->name = newName;

    printf("Enter information about the tour stop. Max number of characters you can enter is 1000.\n");
    char newDescription[1000];
    newNode->info = newDescription;
    fgets(newDescription, sizeof(newDescription), stdin);
    return newNode;
}
4

3 回答 3

3

您没有将字符串复制到结构中。您只是将指针复制到内部的局部变量createNewNode()

char newName[100];
fgets(newName, sizeof(newName), stdin);
newNode->name = newName;

这意味着当您以后访问该存储的指针时未定义的行为,因为它不再有效。

您需要在结构内有字符空间,并复制(或只是读取)其中的字符串,以便只要节点存在,它就会保持分配状态。

于 2013-11-05T08:31:05.860 回答
1

这段代码有很多问题,我什至不知道从哪里开始。

printf("What is the stop you want the new stop to come after? Type 'end' to insert at the end of the tour.");
char key[100];
scanf("%s", &key);
getchar();

如果您绝对需要使用 scanf(建议不要)读取字符串,您应该在 '%s' 格式说明符之前添加要读取的最大字符数,例如 scanf("%99s", &key)。您应该读取 99 个字符而不是 100 个字符,以便空终止不会溢出您的数组。

else if(key == "end")
{
    //code
}

这里不是将 key 的内容与 const char* "end" 进行比较,您只需将数组key的地址与 const char* "end" 的地址进行比较,您应该使用 strcmp代替。(甚至更好的 strncmp

node* createNewNode()
{
    node *newNode;
    newNode = malloc(sizeof(struct node));

    printf("Enter the name of the new tour stop.\n");
    char newName[100];
    fgets(newName, sizeof(newName), stdin);
    newNode->name = newName;

    printf("Enter information about the tour stop. Max number of characters you can enter is 1000.\n");
    char newDescription[1000];
    newNode->info = newDescription;
    fgets(newDescription, sizeof(newDescription), stdin);
    return newNode;
}

这里新节点的名称和信息指针将指向调用createNewNode返回后已释放的内存。这是未定义的行为,您的程序可能会出现段错误或更糟。

您应该将读取缓冲区复制到堆上分配的新缓冲区并将指针设置为指向它们,或者首先在堆上分配缓冲区。

int newDescriptionLength = strlen(newDescription) + 1; //plus 1 for null termination
char* newDescriptionCopy = malloc(newDescriptionLength);
strncpy(newDescriptionCopy, newDescription, newDescriptionLength);
newNode->info = newDescriptionCopy;

strncpy将确保您的 newDescriptionCopy 字符串在源字符串 newDescription 的所有字符都被复制后以空字符结尾。

释放节点时应考虑分配的缓冲区。

此外,您也应该使用 fgets 少读一个字符,因为提供允许的确切字符数不会终止您的字符串。

您应该在深入研究问题之前解决这些问题,因为您的程序充满了未定义的行为,并且在调试期间做出假设是不安全的。

于 2013-11-05T08:58:23.613 回答
0

从我对您的代码的了解(您没有打印调用函数或链表的初始化,如果有的话),看起来您从未检查过第一个元素(即头)。因此,当列表完全为空时,head 将指向 NULL。因此,以您的打印功能为例,您应该拥有:

void printList(node *head)
{
    node *p;
    p = head;

    // Check if the list contains anything
    if (p == NULL)
    {
        printf("List is empty");
    }
    else
    {
        printf("Tour Stop: %s - Description: %s\n", p->name, p->name); // print first/head element

        // Continue while there are more elements
        while(p->next != NULL)
        {
            printf("Tour Stop: %s - Description: %s\n", p->name, p->name);
            p = p->next;
        }
    }
}

您的插入功能可能相同,因此您从不插入任何东西?

注意:Unwind 在他的回答中也有一个非常有效的观点

于 2013-11-05T08:43:08.307 回答