我遇到了一个奇怪的错误,我一生都无法弄清楚它。我有一个函数,可以根据另一个编码函数将字节数组解码为字符串。解码的函数大致如下所示:
char *decode_string( uint8_t *encoded_string, uint32_t length,
uint8_t encoding_bits ) {
char *sequence_string;
uint32_t idx = 0;
uint32_t posn_in_buffer;
uint32_t posn_in_cell;
uint32_t encoded_nucleotide;
uint32_t bit_mask;
// Useful Constants
const uint8_t CELL_SIZE = 8;
const uint8_t NUCL_PER_CELL = CELL_SIZE / encoding_bits;
sequence_string = malloc( sizeof(char) * (length + 1) );
if ( !sequence_string ) {
ERR_PRINT("could not allocate enough space to decode the stringn");
return NULL;
}
// Iterate over the buffer, converting one nucleotide at a time.
while ( idx < length ) {
posn_in_buffer = idx / NUCL_PER_CELL;
posn_in_cell = idx % NUCL_PER_CELL;
encoded_nucleotide = encoded_string[posn_in_buffer];
encoded_nucleotide >>= (CELL_SIZE - encoding_bits*(posn_in_cell+1));
bit_mask = (1 << encoding_bits) - 1;
encoded_nucleotide &= bit_mask;
sequence_string[idx] = decode_nucleotide( encoded_nucleotide );
// decode_nucleotide returns a char on integer input.
idx++;
}
sequence_string[idx] = ' ';
printf("%s", sequence_string); // prints the correct string
return sequence_string;
}
错误是返回指针,如果我尝试打印它,会导致分段错误。但是在函数内部调用printf("%sn", sequence_string)
就可以打印所有内容。如果我像这样调用函数:
const char *seq = "AA";
uint8_t *encoded_seq;
encode_string( &encoded_seq, seq, 2, 2);
char *decoded_seq = decode_string( encoded_seq, 2, 2);
if ( decoded_seq ) {
printf("%sn",decoded_seq); // this crashes
if ( !strcmp(decoded_seq, seq) ) {
printf("Success!");
}
然后它会在打印上崩溃。 一些注意事项,其他功能似乎都可以工作,我已经相当彻底地测试了它们(即decode_nucleotide
,encode_string
(。该字符串也会在函数内正确打印。只有在函数返回后,它才会停止工作。 我的问题是,什么可能导致此内存仅通过从函数返回指针而变得无效?提前感谢!
首先(不是那么重要,但是(在语句中:
sequence_string = malloc( sizeof(char) * (length + 1) );
根据定义,sizeof(char)
始终是 ==1
. 所以语句变成:
sequence_string = malloc(length + 1);
在帖子的这一部分中:
char *decoded_seq = decode_string( encoded_seq, 2, 2);
。由于我看不到您对decode_string
的实现,因此我只能在返回之前假设您如何验证其输出。 但是,我知道您希望返回值包含 C 字符串的合法内容的值。 我还可以假设,因为您正在使用编码和解码,因此输出类型可能unsigned char
。 如果我是对的,那么无符号字符输出类型的合法字符范围是 0-255。
在将值发送到printf
语句之前,您不会检查输出。如果decoded_seq
内存地址处的值恰好是0
,(在unsigned char
范围内(你的程序将崩溃。 字符串函数不能很好地处理空指针。
您应该验证_decode_string_将其发送到printf
char *decoded_seq = decode_string( encoded_seq, 2, 2);
if(decoded_seq != NULL)
{
...