C语言 节点的地址在添加到链表时不断相互覆盖



我正在尝试使用 tasklist 并将输出通过管道传输到我的代码并解析每一行,然后创建每个进程的节点。我稍后会过滤它们,但这还没有在代码中。我在LIST有问题.我已经为这个程序实现了 3 个structsLIST(第一个节点的头部,最后一个节点的后部和列表中节点数的计数(、NODE(指向PROCESS_INFO的指针和指向下一个NODE的指针(、PROCESS_INFO(4 个字符的指针,用于进程名称、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("ttIn Loop: Read Node name: %s", list_->rear->data->pName);
return list_;
}

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

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;
}
}

您可能希望像malloc一样NULL检查strdup的结果(不过,只要您了解基本概念,我就懒得将其添加到答案中(。

相关内容

  • 没有找到相关文章

最新更新