Адреса узлов продолжают перезаписывать друг друга при добавлении в связанный список - PullRequest
0 голосов
/ 21 сентября 2019

Я пытаюсь использовать список задач и передать вывод в мой код и проанализировать каждую строку, чтобы затем создать узлы каждого процесса.Позже я буду фильтровать их, но этого пока нет в коде.У меня проблемы с LIST.Я реализовал 3 structs для этой программы: LIST (заголовок для первого узла, задний для последнего узла и счетчик для количества узлов в списке), NODE (указатель на PROCESS_INFO и указатель на следующий NODE), PROCESS_INFO (4 указателя на символы для имени процесса, PID, использования памяти и времени процессора).Я использовал 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_;
}

1 Ответ

0 голосов
/ 21 сентября 2019

Вы не копируете строки для каждого поля ввода, которое найдете.Вместо этого вы держите указатели в своем буфере 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 (хотя мне лень добавлять это в ответ, покаВы получите основную идею).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...