从外部链接函数返回指针崩溃程序

时间:2017-01-20 01:54:39

标签: c pointers overflow

我有一个函数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循环中生成十六进制转换的四重奏时会失败。令人难以置信。

1 个答案:

答案 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];
}