我正在尝试使用任务列表并将输出通过管道传递到我的代码并解析每一行,然后创建每个进程的节点。稍后我将对它们进行过滤,但是代码中还没有。我在使用时遇到问题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] 删除。
我来说两句