Search code examples
cvisual-studio-2012visual-studio-debuggingrelease-mode

C Function returning char pointer gives garbage in "Debug" mode but not in "Release" mode


Just writing a simple C program to read a long binary file, break it into 12-bit chunks with a 4 bit CRC appended, then output to another file. When I run the code in debug mode (Visual Studio 2012), it returns garbage, but as soon as I switch to Release mode it works fine.

Switching back to debug mode doesn't seem to bring back the problem either... just trying to understand what is going on here. Whatever VS is doing with "release mode" makes the code work there, but I always get the same garbage as debug mode when I use Dev-C++ to compile.

EDIT: I have made the suggest change of using malloc in the calc function, and free in my main, but I am still getting garbage output. VS actually crashes on running now.


char * calc(char bit12[])
{
    int r0,r1,r2,r3;
    int i,tmp;
    //char * bit16;
    char * bit16 = malloc(sizeof(char)*(17));
    char bits[16];
    bit16 = &bits[0];
    /* Set registers to zero */
    r0 = r1 = r2 = r3 = 0;
    /* Insert info bits, most significative first */
    for(i=0; i<12; i++) {
        /* shift registers and make mod2 (^) sums */
        tmp = r3;
        r3 = r2;
        r2 = r1 ^ tmp;
        r1 = r0 ^ tmp;
        r0 = (bit12[i] == '0') ? 0 ^ tmp : 1 ^ tmp;
    }
    /* Insert 4 zeros to finish CRC calculation */
    for(i=0; i<4; i++) {
        /* shift registers and make mod2 (^) sums */
        tmp = r3;
        r3 = r2;
        r2 = r1 ^ tmp;
        r1 = r0 ^ tmp;
        r0 = tmp;
    }
    for (i=0;i<12;i++) 
        bit16[i]=bit12[i];
    if (r3 == 1)
        bit16[12]='1';
    else
        bit16[12]='0';
    if (r2 == 1)
        bit16[13]='1';
    else
        bit16[13]='0';
    if (r1 == 1)
        bit16[14]='1';
    else
        bit16[14]='0';
    if (r0 == 1)
        bit16[15]='1';
    else
        bit16[15]='0';

    printf("Internal Function input: %s\nInternal Function output: %s\n", bit12, bit16);

    return bit16;

}


int main(){
    char str[999];
    char *os,outstr[16];
    FILE *dataIn, *dataOut;
    os = &outstr[0];

    dataIn = fopen("data.txt", "r");
    dataOut = fopen("out.txt", "w");

    if(dataIn){
        //printf("test point 1.\n");
        while(fscanf(dataIn, "%s", str)!= EOF){
            os = calc(str);
            fprintf(dataOut,"%0.16s\n", os);
            free(os);
            //printf("input: %s\n", str);
            //printf("output1: %s\n", outstr);
            //printf("output2: %s\n", os);
            system("PAUSE");
        }
        fclose(dataIn);
        fclose(dataOut);
    }else{
        printf("Error opening data!\n");
    }

    printf("end of prog.\n");
    return 0;
}


Solution

  • garbage in “Debug” mode but not in “Release” mode

    Trust me it has nothing to do with that.

    char bits[16]; is a Local (array) variable with automatic storage duration and references to it will become invalid once it leaves its declaring scope, i.e., when your calc function returns. When the function ends, the array ceases to exist and when you access that pointer/address later its Undefined behavior.

    Instead of making a local array placed on stack, malloc it:

    char * bit16 = malloc(sizeof(char)*(17)); //+1 for NUL char 
    //do something
    return bit16;
    

    And use free to clear the memory when you do not need it.

    os = calc(str);
    fprintf(dataOut,"%0.16s\n", os);
    free(os);