1

我正在完成一个循环缓冲区的工作,当它变满时需要将它的大小加倍。但是,我无法弄清楚如何将元素从旧缓冲区复制到新缓冲区中。我的代码如下:

#define startSize 10
#define fiveMin 300

cbuf* cbuf_init(){

    cbuf *buffer = malloc(sizeof(cbuf) + 9 * sizeof(quote));
    buffer->currSize = 0;
    buffer->maxSize = startSize;
    //buffer->startAt = 0;
    buffer->start = 0;
    buffer->end = 0;
    buffer->freeSlots = startSize;
    //buffer->currIndex = 0;
    return buffer;
}

void cbuf_update(cbuf *cb_ptr, unsigned int time, double rate){


    if(cb_ptr->freeSlots == 0){
        printf("EXPANDING CIRCULAR BUFFER!\n");
        cbuf *newBuffer = malloc(sizeof(cbuf) + 19 * sizeof(quote));
        newBuffer->maxSize = cb_ptr->maxSize * 2;
        newBuffer->start = cb_ptr->start;
        newBuffer->end = cb_ptr->end;
        newBuffer->freeSlots = newBuffer->maxSize - cb_ptr->maxSize;
        int x;
        for(x = 0; x < cb_ptr->maxSize; x ++){
            printf("Copying from slot %d\n", x);
            printf("Currently Copying time: %d\t Rate: %f\n", cb_ptr->quoteBuffer[x].time, cb_ptr->quoteBuffer[x].rate);
            newBuffer->quoteBuffer[x].time = cb_ptr->quoteBuffer[x].time;
            newBuffer->quoteBuffer[x].rate = cb_ptr->quoteBuffer[x].rate;
        }
        cb_ptr = newBuffer;

    }

    //If the start pointer has reached the end of the array and there are still free slots back at the beginning of the array, loop back.   
    if(cb_ptr->start == cb_ptr->maxSize && cb_ptr->freeSlots > 0){
        cb_ptr->start = 0;
    };

    cb_ptr->quoteBuffer[cb_ptr->start].time = time;
    cb_ptr->quoteBuffer[cb_ptr->start].rate = rate;
    cb_ptr->start = cb_ptr->start +1;
    cb_ptr->freeSlots = cb_ptr->freeSlots -1;

    //If any quote in the array is older than 5 minutes when compared to the current quote, flag it as null and move the end pointer up one.
    //Also, clear up a freeSlot.
    int x;
    for(x = cb_ptr->end; x < (cb_ptr->start); x ++){

        if((time) - (cb_ptr->quoteBuffer[x].time) >= fiveMin){
            cb_ptr->end = cb_ptr->end + 1;
            cb_ptr->quoteBuffer[x].time = -1;
            cb_ptr->quoteBuffer[x].rate = -1.00;
            cb_ptr->freeSlots = cb_ptr->freeSlots +1;
        }
    }



}


void cbuf_dump(cbuf *cb_ptr){
    printf("*****\t DUMPING \t*****\n");

    if(cb_ptr->start > cb_ptr->end){
        int x;
        for(x = cb_ptr->end; x<(cb_ptr->start); x++){
            printf("%d.) time = %d, \t rate = %f\n",x,(cb_ptr->quoteBuffer[x].time),(cb_ptr->quoteBuffer[x].rate));
        }
    }

    /*
    If the start pointer has been wrapped back around to the beginning of the circular buffer, then the end pointer must be at an index that is         greater than the start index. For this, we need to print out the data ranging from the end pointer to the end of the array, and then the        data from the start pointer to the end pointer provided the data isn't flagged as null (having -1 for both entries in the quote struct).
    */
    if(cb_ptr->end > cb_ptr->start){
        int x;
        for(x=cb_ptr->end; x < cb_ptr->maxSize; x ++){
            printf("%d.) time = %d, \t rate = %f\n",x,(cb_ptr->quoteBuffer[x].time),(cb_ptr->quoteBuffer[x].rate));
        }
        int y;
        for(y = 0; y < cb_ptr->start; y ++){
            if(cb_ptr->quoteBuffer[y].time != -1){
                printf("%d.) time = %d, \t rate = %f\n",y,(cb_ptr->quoteBuffer[y].time),(cb_ptr->quoteBuffer[y].rate));
            }
        }
    }

    printf("freeslots = %d\n", cb_ptr->freeSlots);
}

int main(){

    cbuf *cb1 ;

    cb1 = cbuf_init() ;
    cbuf_update(cb1, 60, 1.291) ;
    cbuf_update(cb1, 63, 1.287) ;
    cbuf_update(cb1, 63, 1.231) ;
    cbuf_update(cb1, 69, 1.229) ;
    cbuf_update(cb1, 72, 1.247) ;
    //cbuf_dump(cb1);
    cbuf_update(cb1,361,1.291);
    //cbuf_dump(cb1);

    cbuf_update(cb1, 411, 1.291) ;
    //cbuf_dump(cb1);
    cbuf_update(cb1, 412, 1.281) ;
    cbuf_update(cb1, 413, 1.292) ;
    cbuf_update(cb1, 414, 1.284) ;
    //cbuf_dump(cb1);
    cbuf_update(cb1, 414, 1.290) ;
    //cbuf_dump(cb1);
    //cbuf_update(cb1, 415, 1.290) ;
    //cbuf_dump(cb1);

    cbuf_update(cb1, 511, 1.241) ;
    cbuf_update(cb1, 512, 1.251) ;
    cbuf_update(cb1, 513, 1.232) ;
    cbuf_update(cb1, 514, 1.202) ;
    cbuf_update(cb1, 517, 1.119) ;
    cbuf_dump(cb1);
    return 0;

}

当它尝试插入最后一个引号并需要扩展时,问题主要存在(最后一个引号是:

cbuf_update(cb1, 517, 1.119)

我的困惑是如何将 newBuffer cbuf 结构分配给 cb_ptr 缓冲区。它们都是指向 cbufs 的指针,但是如何将 cb_ptr 分配给 newBuffer 呢?

我的输出目前是:

EXPANDING CIRCULAR BUFFER!
Copying from slot 0
Currently Copying time: 414  Rate: 1.290000
Copying from slot 1
Currently Copying time: 511  Rate: 1.241000
Copying from slot 2
Currently Copying time: 512  Rate: 1.251000
Copying from slot 3
Currently Copying time: 513  Rate: 1.232000
Copying from slot 4
Currently Copying time: 514  Rate: 1.202000
Copying from slot 5
Currently Copying time: 361  Rate: 1.291000
Copying from slot 6
Currently Copying time: 411  Rate: 1.291000
Copying from slot 7
Currently Copying time: 412  Rate: 1.281000
Copying from slot 8
Currently Copying time: 413  Rate: 1.292000
Copying from slot 9
Currently Copying time: 414  Rate: 1.284000
*****    DUMPING    *****
freeslots = 0
4

1 回答 1

2

除了数组(衰减为指向其基址的指针)之外,如果要修改它,C 中的所有内容都必须通过地址传递,包括指针。像其他任何事情一样,将参数声明为指向要修改的类型的指针(在这种情况下,它将是指向 cbuf 的指针),然后在调用方传递指针的地址

我能想到的对您的代码的最小更改是:

void cbuf_update(cbuf **cb_pptr, unsigned int time, double rate)
{
    // extract pointer value stored in in/out parameter
    cbuf *cb_ptr = *cb_pptr;

    if(cb_ptr->freeSlots == 0)
    {
        printf("EXPANDING CIRCULAR BUFFER!\n");
        cbuf *newBuffer = malloc(sizeof(cbuf) + 19 * sizeof(quote));
        newBuffer->maxSize = cb_ptr->maxSize * 2;
        newBuffer->start = cb_ptr->start;
        newBuffer->end = cb_ptr->end;
        newBuffer->freeSlots = newBuffer->maxSize - cb_ptr->maxSize;
        int x;
        for(x = 0; x < cb_ptr->maxSize; x ++){
            printf("Copying from slot %d\n", x);
            printf("Currently Copying time: %d\t Rate: %f\n", cb_ptr->quoteBuffer[x].time, cb_ptr->quoteBuffer[x].rate);
            newBuffer->quoteBuffer[x].time = cb_ptr->quoteBuffer[x].time;
            newBuffer->quoteBuffer[x].rate = cb_ptr->quoteBuffer[x].rate;
        }
        free(cb_ptr);
        *cb_pptr = cb_ptr = newBuffer;
    }

    //If the start pointer has reached the end of the array and there are still free slots back at the beginning of the array, loop back.
    if(cb_ptr->start == cb_ptr->maxSize && cb_ptr->freeSlots > 0){
        cb_ptr->start = 0;
    };

    cb_ptr->quoteBuffer[cb_ptr->start].time = time;
    cb_ptr->quoteBuffer[cb_ptr->start].rate = rate;
    cb_ptr->start = cb_ptr->start +1;
    cb_ptr->freeSlots = cb_ptr->freeSlots -1;

    //If any quote in the array is older than 5 minutes when compared to the current quote, flag it as null and move the end pointer up one.
    //Also, clear up a freeSlot.
    int x;
    for(x = cb_ptr->end; x < (cb_ptr->start); x ++){

        if((time) - (cb_ptr->quoteBuffer[x].time) >= fiveMin){
            cb_ptr->end = cb_ptr->end + 1;
            cb_ptr->quoteBuffer[x].time = -1;
            cb_ptr->quoteBuffer[x].rate = -1.00;
            cb_ptr->freeSlots = cb_ptr->freeSlots +1;
        }
    }
}

相信我,没有比这更微小的变化了。不幸的是,您将不得不更改所有更新调用。没有绕过那个。他们将采取这种形式:

cbuf_update(&cb1, 60, 1.291);

如果你在调用方释放这个东西,正常释放:

free(cb1);

希望这是有道理的。绝对探索memcpy()实际数据副本的优点。它将大大减少混乱。

于 2013-04-30T02:49:40.190 回答