我正在尝试修复我的功能,我设置已分配空间的第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 ;
}
答案 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);