1

Cを実装する次の関数を実装するタスクが与えられましたC vector

 40 CVector *CVectorCreate(int elemSize, int capacityHint, CVectorCleanupElemFn fn)
 41 {
 42     //allocate a new CVector struct
 43     CVector *cvector = (CVector*)calloc(1, sizeof(CVector));
 44     assert(cvector != NULL);
 45     //allocate space for the buffer
 46     cvector->vector = calloc(capacityHint, elemSize);
 47     assert(cvector->vector != NULL);
 48     /*
 49      * Use these in other to make the code more efficient
 50      * and also there is going to have less coding in other to
 51      * perform the same operation
 52      * I'm also going to explicity initialize all the members of
 53      * vector even though I don't need
 54      */
 55     cvector->capacity = capacityHint;
 56     cvector->elemSize = elemSize;
 57     cvector->head = cvector->tail = 0;
 58     return cvector;
 59 }

CVectorまた、次の構造体として定義しました。

 17 typedef struct CVectorImplementation {
 18     // include your desired fields here
 19     int head;
 20     int tail;
 21     int numElements;
 22     int capacity;
 23     int elemSize;
 24     void* vector;
 25 }CVector;

ただし、 function の頭にはCVectorCreateCVectorCleanupElemFnスマートポインターを使用するためのものと思われる がありますが、その関数を構造体に含める/使用する方法がわかりません。より経験のある人が、その目的CVectorCleanupElemFnと使用方法を教えてください。次の機能もあります(Timoの提案が導入されました):

 63 void CVectorDispose(CVector *cv)
 64 {
 65     assert(cv != NULL);
 66     // I would imagine cleanUp holds the function
 67     // that empties the buffer
 68     int index = cv->head;
 69     while(index <= tail) {
 70         (cv->cleanupFn)(cv->vector[index]);
            ++index;
 71     }
 72     free(cv->vector);
 73     // finally free the struct cv
 74     free(cv);
 75 }

どうすればそれらを結び付けることができるかを考えています。

4

1 に答える 1

1

私が正しく理解していれば、ベクトル内の個々の要素をクリーンアップするために cleanup 関数が使用されます。(C++ 用語では、要素タイプのデストラクタになります。) したがって、ベクトルから要素を削除するときはいつでも、その要素に対してクリーンアップ関数を呼び出す必要があります。おそらく次のように定義されています。

typedef void (*CVectorCleanupElemFn)(void*);

したがって、構造体に関数ポインターを格納するだけです

typedef struct CVectorImplementation {
    // include your desired fields here
     int head;
     int tail;
     int numElements;
     int capacity;
     int elemSize;
     void* vector;
     CVectorCleanupElemFn cleanupFn;
} CVector;

そして、あなたはそれを次のように呼びます:

(*cvector->cleanupFn)(pointerToTheElement)

編集: CVectorDispose 関数では、アイデアは正しいですが、少しバグがあります。void ポインターをバッファーに格納しているので、それを変換しchar*て演算を行う必要があります。また、要素のサイズを考慮する必要があります。

(*cv->cleanupFn)((char*)cv->vector + index * cv->elemSize);

tail が最後の要素の 1 つ後のインデックスである場合、ループは 1 つの要素が長すぎます。する必要があります

while(index < tail)
于 2013-03-23T14:58:32.523 に答える