2012-03-05 11 views
0

ちょっとC++プログラムをC言語に移植して単純化しました。C言語の構造体を使用してC++クラスから継承をシミュレートするときに次のコードを使用しています。C "模擬継承"中に異なる構造体ポインタをキャストする

typedef struct GenTask GenTask; 
typedef struct Task Task; 
typedef struct UserTask UserTask; 

struct GenTask{ 
    char name[MAXCHAR]; 
    boolean isUserTask; 
    int k; 
    void (*print)(Task*); 
}; 

GenTask* newGenTask(const char* n){ 
    GenTask* inhTask = (GenTask*)malloc(sizeof(GenTask)); 
    strncpy(inhTask->name, n, MAXCHAR); 
    inhTask->k = 1; 
    return inhTask; 
} 

struct Task{ 
    GenTask* inhTask; 
}; 

void printTask(Task* task){ 
    printf("\nThis is Task: %s",task->inhTask->name); 
} 

Task* newTask(const char* n){ 
    Task* task = (Task*)malloc(sizeof(Task)); 
    task->inhTask = newGenTask(n); 
    task->inhTask->isUserTask = false; 
    task->inhTask->print = printTask; 
    return task; 
} 

void deleteTask(Task* task){ 
    free(task->inhTask); 
    free(task); 
} 

struct UserTask{ 
    GenTask* inhTask; 
    int m; 
}; 

void printUserTask(Task* task){ 
    UserTask* ut = (UserTask*)task; 
    printf("\nThis is UserTask nbr: %d",ut->m); 
} 

UserTask* newUserTask(const char* n){ 
    UserTask *ut = (UserTask*)malloc(sizeof(UserTask)); 
    ut->inhTask = newGenTask(n); 
    ut->inhTask->isUserTask = true; 
    ut->inhTask->print = printUserTask; 
    ut->m=100; 
    return ut; 
} 

void deleteUserTask(UserTask* utask){ 
    free(utask->inhTask); 
    free(utask); 
} 

私はコードを実行しようとしましたが、期待どおりに動作します。しかし、私の質問は、余分な "UserTask-memory"が以下のような型キャストの後に公開される危険があるかどうかです。

Task* task = (Task*)newUserTask("A UserTask"); 

私はUserTaskポインタにキャストするときに問題はないようです。

UserTask* utask = (UserTask*)task; 

私は "A UserTask" のためにメモリを解放するとき、私は自由utaskにsuffiesとdeleteUserTask(utask)を使用していると仮定しますか?代わりにdeleteTask(タスク)を使用してタスクを解放すると、UserTask固有のメモリが解放されないと思います。

私はC++とCの両方で新しく、以前はJavaを使用していましたが、動的メモリ割り当てはまだ少し怖いです...助けてくれてありがとう!

/パトリック

答えて

2

私はCでこれを行うには、「正常」な方法、すなわち、ポインタとして親構造体をインラインで含めることではないと思います。

struct Task{ 
    GenTask inhTask; 
}; 

そのようにタスクへのポインタ構造体はTask *にキャストアップできます。もちろん、「親」は子インスタンスとともに自動的に解放されます。

+0

はい私もそれを見ました。私がしなかった理由は、GenTask-structにもポインタが含まれているため(実装上)、そのメモリを解放する必要があります。しかし、ええ、私はまだそれがポインタとして持っていることは少し還元されている方法を参照してください。それを変えるかもしれない。しかし、「タスク構造体へのポインタがタスク*にキャストアップできるようにする」の中で、「タスク」によって明示的に意味するものは何ですか? GenTaskを持つすべての構造体?回答ありがとうございます –

+0

タスク*があれば、明示的に逆参照するのではなく、透明にGenTask *として扱うことができます。 GenTask *に構造体が削除されたときに解放されなければならないメモリへのポインタがある場合、すべての 'サブ構造体'についても同様に行う必要があります。 –

関連する問題