新的C,怪异的calloc()事件

时间:2014-04-07 19:29:09

标签: c

我使用calloc()分配内存但是当我调用calloc来分配更多内存时,它会被清除,稍后在程序中。我在conv2bin里面调用了calloc num1bin,然后当我调用我的luiArray时它被清除回所有的0。这是它应该如何工作的?我错过了什么吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

typedef int bool;

void printBinary(bool* bin, int size, FILE* outfile)
{
    for(int i=0; i<size; ++i)
    {
        fprintf(outfile, "%d", bin[i]);
    }
}

void printHex(char* hex, int size, FILE* outfile)
{
    for(int i=0; i<size; ++i)
    {
        fprintf(outfile, "%c", hex[i]);
    }
}

bool* conv2bin(int num)
{
    bool* bin = (bool*) calloc(1, 16);
    if(num > 65535 || num < 0)
    {
        fprintf(stderr, "NUMBER NOT AVAILABLE FOR 16BIT UNSIGNED BINARY\n");
        exit(1);
    }
    int j = 0;
    for(int i=15; i>=0; --i, j++)
    {
        if(num >= (int) pow(2, i))
        {
            bin[j] = 1;
            num -= (int) pow(2,i);
        }
        else
        {
            bin[j] = 0;
        }
    }
    if(num != 0)
    {
        fprintf(stderr, "FUNCTION FAILED\n\n");
        printBinary(bin, 16, stderr);
        fprintf(stderr, "\n");
        exit(1);
    }

    return bin;
}

char* conv2hex(bool* bin)
{
    char* hex = (char*) calloc(1, 5);
    int j=0;
    for(int i=0; i<16; i+=4, ++j)
    {
        int hchar = 0;
        if(bin[i] == 1)
        {
            hchar += 8;
        }
        if(bin[i+1] == 1)
        {
            hchar += 4;
        }
        if(bin[i+2] == 1)
        {
            hchar += 2;
        }
        if(bin[i+3] == 1)
        {
            hchar += 1;
        }

        if(hchar < 10)
        {
            hex[j] = (char)(((int)'0')+hchar);
        }
        else if(hchar == 10)
        {
            hex[j] = 'A';
        }
        else if(hchar == 11)
        {
            hex[j] = 'B';
        }
        else if(hchar == 12)
        {
            hex[j] = 'C';
        }
        else if(hchar == 13)
        {
            hex[j] = 'D';
        }
        else if(hchar == 14)
        {
            hex[j] = 'E';
        }
        else if(hchar == 15)
        {
            hex[j] = 'F';
        }
    }
    return hex;
}

int multiply(int num1, int num2)
{
    for(int i=0; i<num2; ++i)
    {
        int carry;
        while(num2 != 0)
        {
            carry = (num1 & num2) << 1;
            num1 ^= num2;
            num2 = carry;
        }
    }
    return num1;
}

int divide(int num1, int num2, int* remain)
{
    int quotient = 0;
    if(num1 == num2)
    {
        (*remain) = 0;
        return 1;
    }
    else if(num1 < num2)
    {
        (*remain) = num1;
        return 0;
    }
    do
    {
        num2 <<= 1;
        quotient <<= 1;
    } while(num2 <= num1);

    return quotient = quotient + divide((num1 - num2), num2, remain);
}

int main(int argc, char **argv)
{
    FILE* infile;
    FILE* outfile;
    infile = fopen(argv[1], "r");
    outfile = fopen(argv[2], "w");

    //check file integrity
    if(infile == NULL)
    {
        fprintf(stderr, "CANNOT OPEN INPUT FILE!\n");
        exit(1);
    }
    if(outfile == NULL)
    {
        fprintf(stderr, "CANNOT OPEN OUTPUT FILE!\n");
        exit(1);
    }

    int num1, num2;
    fscanf(infile, "%d\n%d", &num1, &num2);

    fprintf(outfile, "%d\t%d\n", num1, num2);

    /*SIMULATING LUI AND ORI*/
    bool* num1bin = conv2bin(num1);
    bool* num2bin = conv2bin(num2);

    //print binary numbers
    printBinary(num1bin, 16, outfile);
    fprintf(outfile, "\t");
    printBinary(num2bin, 16, outfile);
    fprintf(outfile, "\n");
    printBinary(num1bin, 16, stderr);

    //allocate memory and write binary numbers into it
    bool* luiArray = (bool*) calloc(1, 32);
printBinary(num1bin, 16, stderr);
    int j=0;
    for(int i=15; i>=0; --i, ++j)
    {
        luiArray[i] = num1bin[j];
    }
    //print out array after first 16 loaded into it
    printBinary(luiArray, 32, outfile);
    fprintf(outfile, "\n");
    j=16;
    for(int i=31; i>=16; --i, ++j)
    {
        luiArray[i] = num1bin[j];
    }

    printBinary(luiArray, 32, outfile);
    fprintf(outfile, "\n");
    free(luiArray);

    /*BITWISE MULTIPLY AND DIVIDE*/
    int product = multiply(num1, num2);
    fprintf(outfile, "%d * %d = %d\n", num1, num2, product);
    int quotient, remain;
    divide(num1, num2, &remain);
    fprintf(outfile, "%d / %d = %d (%d)\n", num1, num2, quotient, remain);

    /*LOGICAL OPERATORS*/
    int andresult = num1 & num2;
    bool* ares = conv2bin(andresult);
    char* hexand = conv2hex(ares);
    printBinary(ares, 16, outfile);
    fprintf(outfile, "\t");
    printHex(hexand, 4, outfile);
    fprintf(outfile, "\n");
    free(ares);

    int orresult = num1 | num2;
    bool* ores = conv2bin(orresult);
    char* hexor = conv2hex(ores);
    printBinary(ores, 16, outfile);
    fprintf(outfile, "\t");
    printHex(hexor, 4, outfile);
    fprintf(outfile, "\n");
    free(ores);

    int xorresult = num1 ^ num2;
    bool* xres = conv2bin(xorresult);
    char* hexxor = conv2hex(xres);
    printBinary(xres, 16, outfile);
    fprintf(outfile, "\t");
    printHex(hexxor, 4, outfile);
    fprintf(outfile, "\n");
    free(xres);

    int notresult = ~num2;
    bool* nres = conv2bin(notresult);
    char* hexnot = conv2hex(nres);
    printBinary(nres, 16, outfile);
    fprintf(outfile, "\t");
    printHex(hexnot, 4, outfile);
    fprintf(outfile, "\n");
    free(nres);

    free(num1bin);
    free(num2bin);

    fclose(infile);
    fclose(outfile);
    free(hexand);
    free(hexor);
    free(hexxor);
    free(hexnot);
    return 0;
}

使用只有两个正数的文本文件(78和123是我正在使用的),由输入返回分隔。输出的任何文本文件。

很抱歉这个混乱。感谢您的帮助。我会在某些时候将pow()更新为bitshift。

2 个答案:

答案 0 :(得分:4)

此代码:

typedef int bool;

表示sizeof(bool) == sizeof(int)。您的分配假定为sizeof(bool) == 1。但是,sizeof(int) > 1。因此,您的程序通过注销数组的末尾来调用未定义的行为。

其他一些评论:

  1. pow()执行浮点运算。这真的不合适。你应该使用按位移位。
  2. 请勿转换malloc()
  3. 的返回值
  4. 您是否确定要输入名为bool的类型?这对我来说似乎有点不明智。我建议您添加stdbool.h并使用标准C bool。当然,您仍然希望使用sizeof()而不是做出任何假设。

答案 1 :(得分:2)

接受回答后

同意大小错误,因为@David Heffernan很好的答案报告。

为避免在第一个位置出现错误,请不要硬编码。让编译器使用sizeof *bin

派生它
 void *calloc(size_t nmemb, size_t size);

 // bool* bin = (bool*) calloc(1, 16);
 bool* bin = calloc(16, sizeof *bin);

次要:
1)精选编译器中可能会出现与calloc()参数顺序有关的细微问题。使用number_of_elements, size_of_one_element)
2)无需转换calloc()返回值。