【发布时间】:2018-10-14 02:29:06
【问题描述】:
我遇到了一个奇怪的错误,我终其一生都无法弄清楚。我有一个函数可以根据另一个编码函数将字节数组解码为字符串。解码的函数大致是这样的:
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 string\n");
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] = '\0';
printf("%s", sequence_string); // prints the correct string
return sequence_string;
}
错误是返回指针,如果我尝试打印它,会导致分段错误。但是在函数内部调用printf("%s\n", 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("%s\n",decoded_seq); // this crashes
if ( !strcmp(decoded_seq, seq) ) {
printf("Success!");
}
然后它会在打印时崩溃。
一些注意事项,其他功能似乎都可以工作,我已经对它们进行了相当彻底的测试(即decode_nucleotide,encode_string)。该字符串还在函数内部正确打印。只有在函数返回后它才会停止工作。
我的问题是,仅通过从函数返回指针可能导致该内存变为无效的原因是什么?提前致谢!
【问题讨论】:
-
我会把它添加进去。但奇怪的是,它似乎做的一切都是正确的。解码后的字符串是正确的并且以空值结尾(即,如果初始字符串是“AA”并且我对其进行编码,然后对其进行解码,它就会给我“AA”,只要我在函数内打印它。
-
为什么有一个额外的参数传递给
printf?您实际上是否在检查my_decoded_sequence是否为 NULL ?你能放一个完全可测试的minimal reproducible example吗?即显示实际执行打印的代码outside。 -
我的问题是它与这个函数本身无关,你可以通过使用 mallocs & inits 一个长度字符串的函数来存根它来显示它。我相信较早的函数已经破坏了堆栈,或者 decode_核苷酸正在破坏堆栈,并且一些以前设置和将来依赖的寄存器会导致您的错误。请问printf()中“2”的作用是什么?
-
请学习如何使用gdb。它有帮助。
-
@mevets 我认为你可能是对的。我将不得不尽可能多地退后一步。不幸的是,我目前无法分享很多代码。
标签: c pointers segmentation-fault