在C中使用智能指针

时间:2013-03-23 14:29:47

标签: c

我被赋予了执行以下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;

但是,在函数CVectorCreate的头部,有一个CVectorCleanupElemFn我想象的是使用智能指针,但我不知道如何包含/使用该函数进入我的结构。请有更多经验的人请告诉我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 }

我正试图弄清楚如何将它们绑在一起。

1 个答案:

答案 0 :(得分:1)

如果我理解正确,清理功能用于清除矢量中的invidual元素。 (在C ++术语中,它将是元素类型的析构函数。)因此,当从向量中删除元素时,应该为元素调用清理函数。它可能定义如下:

typedef void (*CVectorCleanupElemFn)(void*);

所以你只需将函数指针存储在struct

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是一个超过最后一个元素的索引。应该是

while(index < tail)