2011-02-05 21 views
0

私は少し問題があります。私はやっとCで始まりました(C#の背景から)、私は二重ポインタに問題があります。構造体へのポインタへのポインタを操作するには?

次のように私は、構造:

#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 

実装:

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

ので、今、私はProcessInfoインスタンスの全体の多くを管理する必要があります。私はProcessInfo構造体へのポインタへのポインタを保持する別の構造体を書いています。なぜなら、必要に応じてサイズを増減できると思ったからです。

#ifndef __SCHEDULER_H 
#define __SCHEDULER_H 

struct Scheduler 
{ 
    struct ProcessInfo** Processes; 
}; 

struct Scheduler* Scheduler_Allocate(void); 

#endif 

そこで問題は、私はScheduler_Allocateメソッドの内部**プロセスのメンバーを初期化しない方法ですか?どのようにそれにものを追加するのですか?

+2

はC.がSCHEDULER_H'またはアンダースコアで始まらない何か'に名前を変更します。 –

+1

R:あなたはあまりにもペンパンシーだと思います。 –

答えて

1
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++; 

またここに私の例を参照してください。__SCHEDULER_H`が無効である `使用

Array of C structs

+0

すばらしい答え!それはまさに私が探していたものでした。実際には、これはリスト/スタックタイプのオブジェクトを作成します。単純にアイテムを追加または削除するだけです。私はAdd()、AddAt()、Remove()、RemoveAt()...とそのsooooooクールを実装するために、この上に構築しています! – bleepzter

+0

強く型付けされたオブジェクトの代わりにvoid **を使って同じことをすることができるのだろうかと思っていましたか? – bleepzter

+0

@bleepzter:はい、 "struct ProcessInfo"の代わりに "void"を使うことができます。しかし、コンパイラが型情報を必要とするたびにポインタをキャストする必要があります。マクロ/テンプレートを使ってプリプロセッサを使ってもっとうまく解決できるかもしれませんが、詳細を説明するには十分ではありません。 – yankee

0

ポインタへのポインタは、ポインタの配列として初期化されます。したがって、malloc(count * sizeof(ProcessInfo*))を呼び出して初期化してください。このようにして、ProcessInfoへのポインタの配列を取得します。 malloc(sizeof(ProcessInfo))を何度も呼び出して、特定のProcessInfo構造体を作成し、それらにポインタを配置します。

また、user470379は、配列内の項目数を変更するためだけにポインタへのポインタは必要ありません。しかし、あなたのアイデアは実際には悪くない、あなたが望むなら、あなたはそれにとどまることができます。

また、C#に精通しているので、CでArrayListのようなものを書くことをお勧めします。次に、このような多くの状況で使用できます。

1

サイズを増減するためにダブルポインタは必要ありません。通常のポインタと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 */ 

代わりProcessInfo_Allocateを有するので次に、あなたがメモリを割り当てていない以外は同様のほとんどを行うだろうProcessInfo_Initを作成することができます。

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

まずに、あなたの定義を変更します。

typedef struct Scheduler { 
    struct ProcessInfo** Processes; 
} Scheduler; 

次に、このようなもの:

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; 
+1

'malloc'の戻り値をチェックすることは悪い考えではありません。 – user470379

+0

ありがとう、私はそれを忘れてしまった:P私は自動的にすべての私のためにこれを行うラッパー関数を使用しています。これを反映するように編集されました。 – atx

1
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 
} 
関連する問題