使用realloc后设置一点

时间:2018-02-17 17:34:54

标签: c bit realloc

我正在尝试修复我的功能,我设置已分配空间的第N位。如果N的大小大于malloc'd空间的大小,则重新分配更多空间以便能够设置第N位。

我的问题是每当我设置的位数高于分配的空间时,它会设置两位。我现在已经玩了一段时间,我觉得很难过。我觉得问题在于使用realloc错误吗?

一个例子是当我尝试设置第52位时,它会产生这个输出:

0001 0000 0000 0000 0000 0000 0000 0000 0001 0000 0000 0000 0000 0000

第52位和第20位都设置

我在这里复制了我的整个程序:https://repl.it/@dholton/Broken

更具体地说,这是我的功能:

Status bit_flags_set_flag( BIT_FLAGS hBit_flags, int flag_position ) {

  bits *phBit_flags = ( bits * ) hBit_flags ;
  int *new_data = NULL ;

  if ( flag_position < phBit_flags -> capacity ) {

    // Check to see if the bit request to set is lower than the memory allocated.
    *phBit_flags -> data |= ( 1 << flag_position ) ;

  } else if ( flag_position >= phBit_flags -> capacity ) {

    // The bit requested is larger so realloc new data to reach the length of the requested bit.
    new_data = ( int * ) realloc( phBit_flags -> data, ( flag_position / 8 ) + 1 ) ;

    if ( new_data == NULL ) {

      free( new_data ) ;
      return FAILURE ;

    }

    free( phBit_flags -> data ) ;

    phBit_flags -> data = new_data ;
    phBit_flags -> size = flag_position ;
    phBit_flags -> capacity = ( flag_position / 8 + 1 ) * 8 ;
    // capacity is number of bits

    *phBit_flags -> data |= ( 1 << flag_position ) ;
    // Set nth bit

    return SUCCESS ;

  }

  return FAILURE ;

}

3 个答案:

答案 0 :(得分:1)

存在多个问题:

  • 用于存储位的类型int是不合适的:您应该使用unsigned int或只使用unsigned char

  • 用于设置位的方法不正确,请参阅下面的更正。

  • 重新分配较大尺寸的数组未初始化为超出原始尺寸的0。成功调用realloc后,您必须自己执行此初始化。

以下是更正后的版本:

typedef struct Bits {
    size_t size;
    size_t capacity;
    unsigned char *data;
} bits;

Status bit_flags_set_flag(BIT_FLAGS hBit_flags, int flag_position) {
    bits *phBit_flags = hBit_flags;

    if (flag_position >= phBit_flags->capacity) {
        // The bit requested is larger so realloc new data to reach the length of the requested bit.
        size_t cur_size = phBit_flags->capacity / 8;
        size_t new_size = flag_position / 8 + 1;
        unsigned char *new_data = realloc(phBit_flags->data, new_size);
        if (new_data == NULL) {
            return FAILURE;
        }
        memset(new_data + cur_size, 0, new_size - cur_size);
        phBit_flags->data = new_data;
        phBit_flags->size = flag_position + 1;
        // capacity is number of bits
        phBit_flags->capacity = new_size * 8;
    }
    // Set nth bit
    phBit_flags->data[flag_position / 8] |= 1 << (flag_position & 7);

    return SUCCESS;
}

答案 1 :(得分:0)

整个街区错了

new_data = ( int * ) realloc( phBit_flags -> data, ( flag_position / 8 ) + 1 ) ;

if ( new_data == NULL ) {

  free( new_data ) ;
  return FAILURE ;

}

free( phBit_flags -> data ) ;

phBit_flags -> data = new_data ;
phBit_flags -> size = flag_position ;
phBit_flags -> capacity = ( flag_position / 8 + 1 ) * 8 ;

realloc可能会返回NULL,您需要检查,free(new_data) 基本上做free(NULL)。您应该释放原始指针并将其设置为NULL

if(new_data == NULL)
{
    free(phBit_flags->data);
    phBit_flags->data = NULL;
    return FAILURE;
}

如果realloc确实返回指针,则它可能是一个新指针。如果它是新的 指针,realloc已经释放了旧记忆,你不必这样做。

因此请在分配前删除free( phBit_flags -> data ) ; phBit_flags->data = new_data

我不确定分配大小是否正确。通常你通过乘法分配 sizeof(int)sizeof *var所需的新尺寸。但是( flag_position / 8 ) + 1 不这样做,实际上它甚至不是倍数或4(假设一个大小 int等于4),因此您可能会分配比您需要的空间更少的空间。

*phBit_flags -> data |= ( 1 << flag_position ) ;

仅当flag_position不大于31时才会起作用(同样, asumming 4的大小为int)。所以你必须计算在哪个字节 你需要做转移。

如果你想拥有比int更多的位,那么你可以分配一个 int的数组,在数组中使用例如小端,意思是 最低有效位应在data[0]中。

我不理解你flag_position / 8计算,8来自哪里 从?如果flag_position例如为35,则35 / 8*sizeof(int)会给出 1,而35 % 8*sizeof(int)会给你3,所以第35位将在 你必须设置data[1]的第3位。

所以realloc应该是

new_data = realloc( phBit_flags -> data,
        ((flag_position / 8*sizeof(phBit_flags->data) + 1) * sizeof *phBit_flags->data);

(flag_position / 8*sizeof(phBit_flags->data) + 1会给你多少 int你需要sizeof *phBit_flags->data);int给你一个大小 size_t idx = flag_position / (8 * sizeof *phBit_flags->data); size_t bit = flag_position % (8 * sizeof *phBit_flags->data); phBit_flags->data[idx] |= (1 << bit);

所以设置位:

with open('somefile.txt', 'r') as file:
    for line in file:
        find = 'some string'
        if find in line:
            if previous line is the same as this line: #how to write this ?
                pass
            else:
                print(line)

答案 2 :(得分:0)

*phBit_flags -> data |= ( 1 << flag_position ) ;

应该是

size_t pos = flag_position / (8 * sizeof phBit_flags->data[0]);
size_t bit = flag_position % (8 * sizeof phBit_flags->data[0]);

phBit_flags -> data[pos] |= ((typeof(phBit_flags->data[0]))(1) << bit);