在C中重置char缓冲区

时间:2012-09-22 20:52:23

标签: c memory-management struct

我正在做家庭作业,我需要基本上创建一个字符缓冲区。我需要创建的一个函数叫做“b_reset”。它的目的是重新初始化给定的缓冲区,使其指向char缓冲区中的第一个位置。这是必需的,因为稍后,当一个新的char被添加到缓冲区时,它需要被添加到缓冲区中的第一个位置。

这是我到目前为止的代码:

结构:

typedef struct BufferDescriptor {
    char * ca_head ;
    int capacity ;
    char inc_factor;
    int addc_offset ;
    int mark_offset ;
    char r_flag;
    char mode;
} Buffer ;

代码:

int b_reset ( Buffer *pB )
{
    Buffer *temp = NULL;
    int i = 0;
    int j = 1;

    if (pB == NULL)
    {
    return R_FAIL_1;
    }
    else
    {
        temp = (Buffer*)malloc(sizeof(Buffer*));
        if (temp == NULL)
        {
            return R_FAIL_1;
        }
        temp->ca_head = (char*)malloc(pB->capacity);
        if (!temp->ca_head)
        {
            temp = NULL;
            return R_FAIL_1;
        }

        for(i = 0;i < ca_getsize(pB);++i)
        {
            temp->ca_head[j] = pB->ca_head[i];
            j++; 
        }

        pB->ca_head = temp->ca_head;

        //free(temp->ca_head);
        //free(temp);

        return 0;
    }
}

我在这段代码中的目标是创建一个临时缓冲区,它基本上会根据实际给定的缓冲区移动一次。这会使第一个位置为空,因此可以添加另一个char。

我遇到的问题是原始缓冲区在重置后似乎没有返回正确的值。

当我这样做时:

temp->ca_head[0] = 'a';
temp->ca_head[1] = 'b';
temp->ca_head[2] = 'c';
temp->ca_head[3] = 'd';
temp->ca_head[4] = 'e';

b_reset(temp); //this will return the size as 0, when it's actually 5

//temp->ca_head[0] = 'i'; //if this is executed, it returns the size as 6 
                          //and prints out the right values, but if it's not, 
                          //it will not print out anything

printf("%d", ca_getsize(temp));
for(i = 0;i < ca_getsize(temp);++i)
{
    printf("%c", temp->ca_head[i]);
}

我知道这里出了点问题,但我不太清楚是什么。任何建议都将不胜感激。

3 个答案:

答案 0 :(得分:0)

    temp = (Buffer*)malloc(sizeof(Buffer*));

您需要分配足够的空间来容纳Buffer,但是您只需要分配足够的空间来容纳指向缓冲区的指针。这应该是:

    temp = (Buffer*)malloc(sizeof(Buffer));

答案 1 :(得分:0)

您正在错误地管理您的记忆。你正在为一个新的Buffer结构分配内存,而实际上你只需要处理ca_head成员的内存(如果我对你的作业问题的解释是正确的)。

每次调用b_reset时,都将为此结构分配不会释放的内存。如果您没有正确处理内存,您将遇到意想不到的结果,就像您在问题中报告的那样。

我建议你对函数realloc进行研究,并在b_reset函数中正确使用它。

祝你的作业好运。

答案 2 :(得分:0)

此代码基于您的后续评论:

  好吧,我不是要尝试调整缓冲区大小,我只是想创建一个   在第一个位置空的空间,所以基本上把一切都转移到   正确的一次。假设有足够的空间   缓冲区来处理这个过程。

我认为你不需要在初始版本之外做任何malloc()。你可以把一切都放在一个循环中:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define R_FAIL_1 1

#define BUFFER_SIZE 10

typedef struct BufferDescriptor {
    char * ca_head ;
    int capacity ;
    char inc_factor;
    int addc_offset ;
    int mark_offset ;
    char r_flag;
    char mode;
} Buffer ;

void allocate_buffer(Buffer *pB, int size)
{
   pB->ca_head = malloc(size);
   assert(pB->ca_head);
   pB->capacity = size;
}

int ca_getsize( Buffer *pB)
{
   return pB->capacity;
}


int b_reset ( Buffer *pB )
{
   int i = 0;

   if (pB == NULL)
   {
      return R_FAIL_1;
   }
   else
   {
      if ( ca_getsize(pB) <= 0 || pB->ca_head == NULL ) 
         return R_FAIL_1;
   }
   // shift data up by 1 byte
   for( i = ca_getsize(pB) - 1 ; i > 0;i-- )
   {
      pB->ca_head[i] = pB->ca_head[i-1];
   }
   pB->ca_head[0] = '\0';
   return 0;
}

void print_buffer(Buffer *pB)
{
   printf("capacity: %d \n", ca_getsize(pB));
   for (int i = 0;i < ca_getsize(pB);++i)
   {
      printf("buffer(%d): [%d] ",i, pB->ca_head[i]);
   }
   printf("\n");
}


int main(void)
{
   Buffer a_buffer;
   allocate_buffer(&a_buffer,BUFFER_SIZE);
   strcpy(a_buffer.ca_head,"abcdefgh");
   print_buffer(&a_buffer);
   int ret = b_reset(&a_buffer);
   assert(ret == 0);
   print_buffer(&a_buffer);
}