链接列表节点被错误覆盖

时间:2018-04-04 07:30:41

标签: c memory linked-list runtime-error dynamic-allocation

我正在使用链接列表在C中创建音乐库程序。用户应该能够创建包含以下内容的节点:歌曲名称,艺术家和流派。这些节点应按歌曲名称的字母顺序排序。

然而,我遇到了麻烦,在不影响我当前头节点的情况下创建新节点。下面的图片将更好地说明这一点。我调用一行代码,用于从用户接收新值,并重置头节点中的歌曲名称值,我不知道为什么。任何帮助表示赞赏。

(测试点1和测试点2 printf语句之间出现问题,我打算让测试点2显示" zz"而不是" aa")。

Code Output

Code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>

typedef struct node
{
    char* artist;
    char* songName;
    char* genre;
    struct node* nextNode;
} Node;

const int MAX_LENGTH = 1024;
void inputStringFromUser(char prompt[], char s[], int arraySize);

int main(void)
{
    // Declare the head of the linked list.
    //   ADD YOUR STATEMENT(S) HERE
    Node* head = NULL;

    // Announce the start of the program
    printf("Personal Music Library.\n\n");
    printf("%s",
           "Commands are I (insert), D (delete), S (search by song name),\n"
           "P (print), Q (quit).\n");

    char response;
    char input[MAX_LENGTH + 1];
    char input4[MAX_LENGTH + 1];
    char input2[MAX_LENGTH + 1];
    char input3[MAX_LENGTH + 1];

        inputStringFromUser("\nCommand", input, MAX_LENGTH);

        response = toupper(input[0]);

        if (response == 'I') {
//insert a node code
            char* promptName = "Song name";
            char* promptArtist = "Artist";
            char* promptGenre = "Genre";
            char* newName;
            char* newArtist;
            char* newGenre;
//test points for the songname in the head node
            if (head != NULL) {
                printf("Test Point 1: %s\n", head->songName);
            }
            inputStringFromUser(promptName, input4, MAX_LENGTH);
            newName = input4;
            if (head != NULL) {
                printf("Test Point 2: %s\n", head->songName);
            }
            inputStringFromUser(promptArtist, input2, MAX_LENGTH);
            newArtist = input2;
            inputStringFromUser(promptGenre, input3, MAX_LENGTH);
            newGenre = input3;
            //if it is the first node then just create a node then assign the values to the user input
            if (head == NULL) {
                head = malloc(sizeof(Node));
                head->artist = newArtist;
                head->genre = newGenre;
                head->songName = newName;
            } else {
//sorts through list until it finds the first node where the song name is not alphabetically ahead
//of the current entered name
                Node* current = head;
                while (strcmp(current->songName, newName) == 1) {


                //if the loop goes to the end of the list place the new node at the end
                    if (current->nextNode != NULL) {
                        current = current->nextNode;
                    } else {
                        current->nextNode = malloc(sizeof(Node));
                        current = current->nextNode;
                        current->artist = newArtist;
                        current->genre = newGenre;
                        current->songName = newName;
                        break;
                    }
                }
//if the loop finds the correct place for a node it shifts all the other ones down
//then create a new end node
                char* tempName = "  ";
                char* tempName2 = "  ";
                char* tempArtist = "  ";
                char* tempArtist2 = "  ";
                char* tempGenre = "  ";
                char* tempGenre2 = "  ";

                tempName = current->songName;
                tempArtist = current->artist;
                tempGenre = current->genre;

                current->artist = newArtist;
                current->genre = newGenre;
                current->songName = newName;

                while (current->nextNode != NULL) {
                    current = current->nextNode;

                    tempName2 = current->songName;
                    tempArtist2 = current->artist;
                    tempGenre2 = current->genre;

                    current->songName = tempName;
                    current->artist = tempArtist;
                    current->genre = tempGenre;

                    tempName = tempName2;
                    tempGenre = tempGenre2;
                    tempArtist = tempArtist2;
                }

                current->nextNode = malloc(sizeof(Node));
                current = current->nextNode;
                current->songName = tempName;
                current->artist = tempArtist;
                current->genre = tempGenre;
            }
        } 
}

// Support Function Definitions

// Prompt the user for a string safely, without buffer overflow
void inputStringFromUser(char prompt[], char s[], int maxStrLength)
{
    int i = 0;
    char c;

    printf("%s --> ", prompt);
    while (i < maxStrLength && (c = getchar()) != '\n')
        s[i++] = c;
    s[i] = '\0';
}

1 个答案:

答案 0 :(得分:0)

这是错误的一个例子:

current->genre = newGenre;

保存指针newGenre的值(指向input3)。因此,所有节点都将指向同一个对象,即当更改input3时,所有节点都将指向新值。

尝试:

typedef struct node
{
    char artist[MAX_LENGTH + 1];
    char songName[MAX_LENGTH + 1];
    char genre[MAX_LENGTH + 1];
    struct node* nextNode;
} Node;

然后执行:

strcpy(current->genre, newGenre);

将值复制到节点中。

或者,您可以保留指针并使用动态内存分配。