我有一个函数bin2hexStr(),它将二进制字符串转换为十六进制字符串。经过测试,它会在最后一次调用时崩溃我的程序'。在此示例之前尝试使用较小输入的许多函数调用是成功的。但我不确定为什么它在这里失败了。此外,如果您从下面删除案例9,它将在案例8中失败,如果按以下方式执行,它将通过案例:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
char bin2hexChar(char*);
int string_compare(char*, char*);
char* bin2hexStr(char*);
int main(void) {
char* bin7 = "101110101111110000110001110010110011110100110101110110";
char* bin25 = "100111010011101101011100111100011010111001000110100001101010";
printf("Case 8: 101110101111110000110001110010110011110100110101110110 (54 bits):\n");
printf("Expected Result: 2EBF0C72CF4D76\n");
printf("Actual Result: %s\n\n", bin2hexStr(bin7));
printf("Case 9: 100111010011101101011100111100011010111001000110100001101010 (60 bits):\n");
printf("Expected Result: 9D3B5CF1AE4686A\n");
printf("Actual Result: %s\n\n", bin2hexStr(bin25));
}
char* bin2hexStr(char* binStr) {
char *paddedBin;
int i,r;
size_t loops;
int count = 0;
r = 4-strlen(binStr)%4;
if(r!=4){
loops = (strlen(binStr)+r)/4;
paddedBin = (char *)malloc((loops+1)*sizeof(char));
for(int j=0; j<r;++j)
paddedBin[j] = '0';
memcpy(paddedBin,&buffer[4-r],r);
memcpy(&paddedBin[r],binStr,strlen(binStr)+1);
}else{
loops = ceil(strlen(binStr)/4);
paddedBin = (char *)malloc((loops+1)*sizeof(char));
memcpy(paddedBin,binStr,strlen(binStr)+1);
}
printf("Printing value of r (zeros to pad): %d\n", r);
char *hexStr = (char *)malloc((loops)*sizeof(char));
for(i=0;i<(int)loops;i++){
char *quartet = (char *)malloc((5)*sizeof(char));
++count;
memcpy(quartet,&paddedBin[4*i],4);
quartet[4]='\0';
hexStr[i] = bin2hexChar(quartet);
free(quartet);
}
hexStr[loops] = '\0';
printf("Printing hex converted string: %s\n", hexStr);
free(paddedBin);
return hexStr;
}
char bin2hexChar(char* bin){
static char hex_table[] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
static char bin_table[16][5] = {"0000", "0001", "0010", "0011", "0100",
"0101","0110", "0111", "1000", "1001",
"1010", "1011", "1100", "1101", "1110",
"1111"};
int i;
int k = 16;
char hex;
for(i=0;i<k;i++){
if (string_compare(bin,bin_table[i])==1) {
hex = hex_table[i];
break;
}
}
return hex;
}
int string_compare(char str1[], char str2[])
{
int ctr=0;
while(str1[ctr]==str2[ctr])
{
if(str1[ctr]=='\0'||str2[ctr]=='\0')
break;
ctr++;
}
if(str1[ctr]=='\0' && str2[ctr]=='\0')
return 1;
else
return 0;
}
通常我将这些函数放在一个单独的文件中并在外部进行链接,但我修改了它以提供一个最小的,完整的,可验证的示例。
有人可以帮忙吗?
编辑:经过更多的调试,在评论出免费(paddedBin)后会产生有趣的行为。如果free(paddedBin)保持取消注释,则在返回hexStr时失败,如上所述。如果注释了free(paddedBin),则在for循环中生成十六进制转换的四重奏时会失败。令人难以置信。
答案 0 :(得分:1)
像这样修复和减少(省略错误检查)
char *bin2hexStr(const char *binStr){
size_t loops, len = strlen(binStr);
int r = len % 4;
if(r)
r = 4 - r;
char *paddedBin = malloc(len + r + 1);//+1 for null-terminator
memset(paddedBin, '0', r);//add padding to top
memcpy(paddedBin + r, binStr, len + 1);
loops = (len + r) / 4;
char *hexStr = malloc(loops + 1);//+1 for NUL
for(size_t i = 0; i < loops; i++){
hexStr[i] = bin2hexChar(paddedBin + i * 4);
}
hexStr[loops] = '\0';
free(paddedBin);
return hexStr;
}
char bin2hexChar(const char *bin){
static char hex_table[] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
int k = 0;
for(int i = 0; i < 4; i++){
k = k * 2 + *bin++ - '0';//calculate index
}
return hex_table[k];
}