How to work with pointer to pointer to a struct?
I have a bit of a problem. I am barely starting out with C, (comming from a C# background) and I am having problem with double pointers.
I have a structure as follows:
#ifndef __PROCESSINFO_H
#define __PROCESSINFO_H
struct ProcessInfo
{
int ProcesId;
int Priority;
int ExecutionTime;
int EllapsedTime;
char* ProcessName;
};
struct ProcessInfo *ProcessInfo_Allocate(int processId, char *processName, int priority, int executionTime);
void ProcessInfo_ToString(struct ProcessInfo *processInfo);
void ProcessInfo_Dispose(struct ProcessInfo *processInfo);
#endif
Implementation:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "processinfo.h"
struct ProcessInfo *ProcessInfo_Allocate(int processId, char *processName, int priority, int executionTime)
{
struct ProcessInfo *processInfo;
processInfo = (struct ProcessInfo *)malloc(sizeof(struct ProcessInfo));
processInfo->ProcessId = processId;
processInfo->ProcessName = processName;
processInfo->Priority = priority;
processInfo->ExecutionTime = executionTime;
processInfo->EllapsedTime = 0;
return processInfo;
}
void ProcessInfo_ToString(struct ProcessInfo *processInfo)
{
printf(" %6i %6i %10i %10i, %25s", processInfo->ProcessId, processInfo->Priority, processInfo->ExecutionTime, processInfo->EllapsedTime, processInfo->开发者_开发知识库ProcessName);
}
void ProcessInfo_Dispose(struct ProcessInfo *processInfo)
{
if(processInfo != NULL)
{
if(processInfo->ProcessName != NULL)
{
free(processInfo->ProcessName);
}
free(processInfo);
}
}
so now I have to manage a whole lot of ProcessInfo instances. I wrote another structure which would hold a pointer to a pointer to the ProcessInfo sturcture because i thought that I can increase and decrease it in size as needed (without too much hassle);
#ifndef __SCHEDULER_H
#define __SCHEDULER_H
struct Scheduler
{
struct ProcessInfo** Processes;
};
struct Scheduler* Scheduler_Allocate(void);
#endif
So the question is how do I initialize the **Processes member inside the Scheduler_Allocate
method? How do I add stuff to it?
struct Scheduler s;
s.Processes = malloc(sizeof(struct ProcessInfo*) * size);
s.Processes[0] = ProcessInfo_Allocate(...);
// Add more items:
s.Processes = realloc(malloc(sizeof(struct ProcessInfo*) * (size + 1));
s.Processes[size] = ProcessInfo_Allocate(...);
size++;
Also see my example here:
Array of C structs
You don't need a double pointer to increase/decrease the size. Just use a normal pointer and realloc
.
struct ProcessInfo* processes = malloc(sizeof(struct ProcessInfo) * 2);
struct ProcessInfo* processes_tmp;
if (!processes) {
/* bail */
}
/* do whatever with processes[0] and [1] */
processes_tmp = processes;
processes = realloc(processes, sizeof(struct ProcessInfo) * 5);
if (!processes) {
free(processes_tmp);
/* bail */
}
/* processes[0] and [1] are unchanged, and [2] [3] and [4] are now valid */
Then instead of having a ProcessInfo_Allocate
, you could create a ProcessInfo_Init
that would do most of the same except not allocating the memory:
int ProcessInfo_Init(struct ProcessInfo *pi, int processId, char *processName, int priority, int executionTime)
{
if (!pi) {
return -1;
}
pi->ProcessId = processId;
pi->ProcessName = processName;
pi->Priority = priority;
pi->ExecutionTime = executionTime;
pi->EllapsedTime = 0;
return 0;
}
size_t size = 10;//or what ever is the number of processes
struct ProcessInfo * process = (struct ProcessInfo *)malloc(size * sizeof(struct ProcessInfo));
if(!process)
//perhaps stop program? Do something
Processes = &process;
//later on
int i;
for(i = 0; i < size; i++)
{
printf("Process id =%d",Processes[i]->ProcesId);
etc
}
Pointer to pointer is initialized as array of pointers. So call malloc(count * sizeof(ProcessInfo*))
to initialize it. This way you get array of pointers to ProcessInfo. Then call malloc(sizeof(ProcessInfo))
many times to create particular ProcessInfo
structures and put pointers to them to the array.
Also, user470379 is right that you don't need pointer to pointer just to change number of items in your array. But your idea is actually not bad either, you can stay with it if you want.
Also, since you are familiar with C#, I would recommend you to start with writing something like ArrayList in C. Then you can use it in many situations (like this one).
First change your definition to:
typedef struct Scheduler {
struct ProcessInfo** Processes;
} Scheduler;
Then something like this:
Scheduler *s;
s = malloc(sizeof(Scheduler));
if (s == NULL) {
exit(-1);
}
s = memset(s, 0, sizeof(Scheduler));
/* Or enter your own memory allocation stuff here */
i = 0; /* Or use some other number */
s->Processes[i] = someProcessInfo;
精彩评论