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

标签 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;
}

通常我将函数放在一个单独的文件中并在外部链接,但我修改了它以提供一个最小的、完整的、可验证的示例。

有人能帮忙吗?

编辑:经过更多调试,在注释掉 free(paddedBin) 时会出现有趣的行为。如果 free(paddedBin) 保持未注释状态,它将在返回 hexStr 时失败,如前所述。如果 free(paddedBin) 被注释,则在 for 循环中生成用于十六进制转换的四重奏时它会失败。令人难以置信。

最佳答案

像这样修复和减少(省略错误检查)

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

关于c - 从外部链接函数返回指针使程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41754850/

相关文章:

c - 在c中跳转未签名的指令

c - 寻找一种在 C 中调用具有不同参数的函数的方法

c++ - C++中的内存分配顺序

c++ - 反向双向链表的前向互惠失败

C++:如何将对象数组传递给函数?

c - 将指针数组传递给函数

c - Makefile - 没有附加参数的行为

c - 为什么在 mac os 上 memchr() 会发生越界

html - 无法在我的 Iframe 中滚动

html - 怎么让:scroll div have the same height of its container?溢出 详细里面