节点的地址在添加到链表中时会相互覆盖

尼克97832954

我正在尝试使用任务列表并将输出通过管道传递到我的代码并解析每一行,然后创建每个进程的节点。稍后我将对它们进行过滤,但是代码中还没有。我在使用时遇到问题LIST我已经structs为该程序实现了3个:(LIST第一个节点的头部,最后一个节点的背面,列表中节点的数量),NODE(指向PROCESS_INFO下一个的指针和指向下一个的指针NODE),PROCESS_INFO(用于进程名称,PID,内存使用情况和cputime)。我曾经printf跟踪过我的代码,直到将它们添加到链接列表之前,一切似乎都能正常工作。每个节点的地址都不同,但是似乎总是会覆盖列表中的最后一个,而不是将节点的新地址添加到上一个节点的下一个*。

我主要是肯定我的算法是正确的,这是我多次使用不同数据的同一算法。我的malloc函数有动态检查,以防万一它们出错了,我已经检查并使用了指针,以防万一我缺少某种形式的取消引用,但是如果我进行了任何更改,都会出错,因此我认为这些问题不足为奇。

我唯一能想到的就是问题所在,那就是所有这些操作都驻留在一个函数的循环中(我读过某个地方,堆栈上的指针不记得它们的地址了吗?)。要解决此问题,我需要更改什么?我已将所有内容移至主要位置,但没有任何更改。

结构定义:

typedef struct processInfo{
    char *pName;
    char *processId;
    char *memUsage;
    char *cpuTime;
}PROCESS_INFO;

typedef struct node{
    PROCESS_INFO* data;
    struct node* next;
}NODE;

typedef struct li{
    int num;
    NODE* head;
    NODE* rear;
}LIST;

主功能:

int main()
{
    LIST* list;
    list = buildList();
    printList(list);
}

列表功能:

//function that creates a new list and returns it as null
LIST* createList()
{
    LIST* newListPtr;
    newListPtr = (LIST*)malloc(sizeof(LIST));

    if (newListPtr)
    {
        newListPtr->num = 0;
        newListPtr->head = NULL;
        newListPtr->rear = NULL;
    }
    return newListPtr;
}

//function that creates the struct for the information of the process
PROCESS_INFO* createPinfo(char* name, char* pid, char* kb, char* cTime)
{
    PROCESS_INFO* pInfoPtr;
    pInfoPtr = (PROCESS_INFO*)malloc(sizeof(PROCESS_INFO));

    if (pInfoPtr)
    {
        pInfoPtr->pName = name;
        pInfoPtr->processId = pid;
        pInfoPtr->memUsage = kb;
        pInfoPtr->cpuTime = cTime;
    }
    return pInfoPtr;
}

//function to create new node and set its data
NODE* createNode(PROCESS_INFO* dataPtr)
{
    NODE* nodePtr;
    nodePtr = (NODE*)malloc(sizeof(NODE));

    if (nodePtr)
    {
        nodePtr->data = dataPtr;
        nodePtr->next = NULL;
    }
    return nodePtr;
}

//Get process information node via the path
PROCESS_INFO* parseInfoFromPath (char str[])
{
    char *pName;
    char *processId;
    char *memUsage;
    char *time;
    char *parse;

    parse = strtok(str, " ");
    pName = parse;

    parse = strtok(NULL, " ");
    processId = parse;

    parse = strtok(NULL, " "); //Console
    parse = strtok(NULL, " "); //session
    parse = strtok(NULL, " "); //memory
    memUsage = parse;

    parse = strtok(NULL, " ");
    parse = strtok(NULL, " ");
    parse = strtok(NULL, " ");
    parse = strtok(NULL, " "); //CPUTIME
    time = parse;

    PROCESS_INFO* pInfoPtr;
    pInfoPtr = createPinfo(pName, processId, memUsage, time); 

    return pInfoPtr;
}

我似乎正在得到语义错误的BuildList()函数:

LIST* buildList()
{
    FILE *fp;
    char path[PATH_MAX];

    fp = popen("tasklist /v /fi \"STATUS eq running\" /nh ", "r");
    if (fp == NULL)
    {
        printf( "CreateProcess failed (%d).\n", GetLastError() );
        return;
    }

    LIST* list_;
    PROCESS_INFO* p;
    NODE* n;
    list_ = createList();

    while (fgets(path, PATH_MAX, fp) != NULL)
    {
        if (path != NULL)
       {
            //create the process info struct
            p = parseInfoFromPath(path);

            //create the node
            n = createNode(p);

            //add node to list
            //if empty list set as head
            if (list_->head == NULL){
                list_->head = n;
            }
            //otherwise set last->next to point to the new node
            else {
                list_->rear->next = n;
            }

            //rear points to last node
            list_->rear = n;
            (list_->num)++;

        }

    }
    //They always print out the same data!!!!
    printf("\nIn Loop: Head Node name: %s", list_->head->data->pName); 
    printf("\t\tIn Loop: Read Node name: %s", list_->rear->data->pName);
    return list_;
}
格莱美

您不会为找到的每个输入字段复制字符串。相反,您将指针保存在path缓冲区中,每次执行操作时该缓冲区都会被覆盖fgets尝试strdup在中使用createPinfo

PROCESS_INFO* createPinfo(char* name, char* pid, char* kb, char* cTime)
{
    PROCESS_INFO* pInfoPtr;
    pInfoPtr = (PROCESS_INFO*)malloc(sizeof(PROCESS_INFO));

    if (pInfoPtr)
    {
        pInfoPtr->pName = strdup(name);
        pInfoPtr->processId = strdup(pid);
        pInfoPtr->memUsage = strdup(kb);
        pInfoPtr->cpuTime = strdup(cTime);
    }
    return pInfoPtr;
}

另外,由于strdup分配了堆内存,所以不要忘记添加一个函数来释放内存,并在每次从列表中删除内容时调用它。例如:

void destroyPinfo(PROCESS_INFO* pInfoPtr)
{
    if (pInfoPtr)
    {
        free(pInfoPtr->pName);
        pInfoPtr->pName = NULL;

        free(pInfoPtr->processId);
        pInfoPtr->processId = NULL;

        free(pInfoPtr->memUsage);
        pInfoPtr->memUsage = NULL;

        free(pInfoPtr->cpuTime);
        pInfoPtr->cpuTime = NULL;
    }
}

您可能想要NULL检查strdup像您一样的结果malloc(不过,只要您有基本的想法,我就懒得将其添加到答案中)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将节点添加到C中的链表时,EXC_BAD访问

创建递归函数以将节点添加到链表中

将节点添加到链表时出现分段错误

如何将链表添加到链表的特定节点上?

如何在没有头/尾指针的情况下将多个节点添加到C中的链表?

将链表中的值添加到变量

如何在链表中执行添加到特定号码?

将节点等级添加到networkx中的节点标签

符石将节点添加到有序链表 - 错误

将节点添加到链表的开头会导致错误消息,我不关注

如何按字母顺序将新节点添加到链表

将头节点添加到单链表中会产生分段错误错误

SEGV:将节点添加到链表的末尾时,大小为8的invalig写

将节点添加到链表的末尾,并具有后方和起始指针

将节点添加到链表的功能不起作用 C

C ++:按字母顺序将节点添加到双向链表

删除链表的最后一个节点,并将其添加到另一个链表

将几个链表的内容添加到较大的链表中并不断更新

给定链表中的节点地址,获取节点的地址

Jstree-添加到节点的多余类在崩溃时会丢失

Sparx EA:将组件添加到节点时会创建什么类型的关系?

使用函数添加到链表

无法添加到链表的头部

将元素添加到链表

将图例添加到ggplot中的覆盖密度图

在设置而非URL中覆盖/添加到Django URL

将多个tds添加到额外的数组中以添加到tr元素节点

如何约束代码中添加到GridPane的节点?

将常规JavaFX节点添加到FXML中