1

我正在为我的系统编程课程编写 Linux 外壳程序。我在为我的命令历史记录部分编写一个链接列表时遇到了一个非常奇怪的情况,我真的不确定我做错了什么。

现在,我将程序设置为接受 char 数组作为输入,并将数据添加到链表末尾的节点中,然后将该节点设置为列表的尾部。然后我让程序从头到尾打印列表。我应该看到的是我输入的内容的历史,以相反的顺序。我所看到的是,我最后输入的内容似乎覆盖了所有先前节点中的数据。

例如:我输入 1,我得到一个 1,然后我输入 2,我得到两个 2,而不是 2,然后是 1。有人知道发生了什么吗?我的代码如下。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INPUT_BUFFER 255

typedef struct commandHistoryNode commandHistoryNode;

struct commandHistoryNode{
    commandHistoryNode *previous;
    commandHistoryNode *next;
    char *commandLine;
};

commandHistoryNode* AddCommandToLinkedList(commandHistoryNode *, char *);
void PrintLinkedList();
void ExecuteCommand(char *);

int main(int argc, char **argv){
    char *cmdString;
    cmdString = calloc(INPUT_BUFFER, sizeof(char));
    char *PS1 = "$";
    commandHistoryNode *currentNode = NULL;
    while(1)
    {
        printf(PS1);
        fgets(cmdString, INPUT_BUFFER, stdin);
        //currentNode is the tail of the LinkedList
        currentNode = AddCommandToLinkedList(currentNode, cmdString);

        PrintLinkedList(currentNode);
    }
}

void ExecuteCommand(char *passedCommand){
   return;
}

commandHistoryNode*
AddCommandToLinkedList(commandHistoryNode *passedNode,  char *passedCommand){
    commandHistoryNode *tailNode = malloc(sizeof(commandHistoryNode));
    tailNode->commandLine = passedCommand;
    if(passedNode == NULL)
    {
        //passedNode is the head of the list
        return tailNode;
    }
    else
    {
        while(passedNode->next!=NULL)
        {
            //if passedNode isn't the tail (and it should be), iterate through the list
            passedNode = passedNode->next;
        }
        //set tempNode to the next node for the passedNode
        passedNode->next = tailNode;
        //set the previous node for tempNode to point to the passedNode
        //as it is the new tail.
        tailNode->previous = passedNode;
    }
    //return new tailNode
    return tailNode;
}

void PrintLinkedList(commandHistoryNode *tailNode){
    while(tailNode != NULL)
    {
        printf("command is: %s\n", tailNode->commandLine);
        //iterate backwards from the tail to the head
        tailNode = tailNode->previous;
    }
}
4

2 回答 2

2

每次调用 AddCommandToLinkedList 时,您都会重复使用相同的 cmdString。所以每个节点都指向同一个字符缓冲区。结果,每次您有一个新命令时,您都会用该命令覆盖唯一的字符缓冲区,并且每个节点都指向它。您需要为每个命令分配一个 cmdString,而不是重复使用它。

于 2013-02-24T00:41:33.543 回答
0

再次检查您返回的内容,以防 passNode 是!= NULL.

于 2013-02-24T00:32:50.990 回答