frostblue
frostblue

Reputation: 176

Simple calloc and FILE code randomly crashes on windows

I have a code that is supposed to generate a curve for regulation purposes which works fine.

Coming from a Linux environment, I did not really know how to code on Windows (which I have to use at work) so I just went on and downloaded Code::Blocks with MinGW.

Now the problem is the following : My code works, but sometimes it crashes. I tried it on Linux and I don't have any problem running it, on Windows however, sometimes it will work, sometimes it won't and tell me this.

Problem signature:
  Problem Event Name:   APPCRASH
  Application Name: TabGen.exe
  Application Version:  0.0.0.0
  Application Timestamp:    02881c68
  Fault Module Name:    ntdll.dll
  Fault Module Version: 6.1.7601.23418
  Fault Module Timestamp:   5708a73e
  Exception Code:   c0000005
  Exception Offset: 00032a62
  OS Version:   6.1.7601.2.1.0.256.48
  Locale ID:    2055
  Additional Information 1: 0a9e
  Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
  Additional Information 3: 0a9e
  Additional Information 4: 0a9e372d3b4ad19135b953a78882e789

To be fairly honest, I don't really understand. I tried looking up "Exception code c0000005 windows" which apparently means "access violation", but I do not understand where it comes from because as stated it sometimes works sometimes it doesn't.

Is it MinGW related ? Have I done something wrong in my code ? I have a function mk_cp_table (which always uses 4096 values, that's why it is not a function parameter) but I'm pretty positive it is alright.

Also if you are wondering why I'm using calloc instead of an array, it's again because of an error I don't understand. The fprintf at the end in the last function did not work if I had my values in an array (however displaying them with printf alone worked perfectly, but fprintf only left blank files whenever I would run it).

Any ideas ?

My code :

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

void tab2file(FILE*, int, int*);
void mk_cp_table (int*, float, float, float, int, float, float, int);

int main (void)
{
    FILE* cp_file = fopen("cp_table.txt", "w");

    if (cp_file == NULL)
    {
        perror("failed fopen for cp_file\n");
        exit(EXIT_FAILURE);
    }

    int* cp_table = calloc((size_t) 4096, sizeof (int));

    if (cp_table == NULL)
    {
        fclose(cp_file);

        perror("failed calloc for cp_table\n");
        exit(EXIT_FAILURE);
    }

    /* Generate curves */

    mk_cp_table(
        cp_table,
        0.142,      /* scale */
        20,         /* zeroed distance 0 (negative part) */
        0.04,       /* slope 0 */
        120,        /* range 0 */
        20,         /* zeroed distance 1 (positive part) */
        0.04,       /* slope 1 */
        120         /* range 1 */
    );

    printf("\ntable generated\n");

    tab2file(cp_file, 4096, cp_table);

    printf("\ntables written to files\n");

    fclose(cp_file);
    free(cp_table);

    return EXIT_SUCCESS;
}

void tab2file(FILE* file, int size, int* table)
{
    int i;

    for (i = 0; i < size; i++)
        fprintf(file, "%d\n", table[i]);
}

void mk_cp_table(int* table, float scale, float zeroes_0, float slope_0, int range_0, float zeroes_1, float slope_1, int range_1)
{
    int i;
    int value;

    zeroes_0 = zeroes_0 / scale;
    zeroes_1 = zeroes_1 / scale;

    for (i = 0; i < 2048; i++)
    {
        if (i < zeroes_1)
            value = 0;

        else
            value = (i - zeroes_1) * slope_1;

        if (value > range_1)
            value = 127;

        table[i] = 0;
    }

    for (i = 0; i < 2048; i++)
    {
        if (i < zeroes_0)
            value = 0;
        else
            value = (zeroes_0 - i) * slope_0;

        if (value < -range_0)
            value = -127;

        table[4096 - i] = value;
    }
}

Upvotes: 0

Views: 211

Answers (3)

Michael
Michael

Reputation: 58497

For an array of 4096 elements, 4095 is the largest valid index you can use. The statement table[4096 - i] = value; writes to table[4096] when i==0, which is outside the bounds of table.

Presumably you meant to do table[4095 - i] = value;, which will give you an index of 4095..2048.

Upvotes: 2

frostblue
frostblue

Reputation: 176

As it turned out it was a segmentation fault, I had table[4096 - i] = value; which would be out of the array's bounds when i was equal to 0.

Sometimes when you focus too much on a part of the code you thought was not working you forget to check the part you thought was working.

Upvotes: 0

gowrath
gowrath

Reputation: 3224

For completeness, so this question doesn't remain in the unanswered section, you are writing out of bounds on the last line of your program in the for loop:

for (i = 0; i < 2048; i++)
{
    if (i < zeroes_0)
        value = 0;
    else
        value = (zeroes_0 - i) * slope_0;

    if (value < -range_0)
        value = -127;

    table[4096 - i] = value;    // out of bounds when i = 0.
}

This is causing the windows equivalent of a seg fault aka access violation. You would notice this on unix too if you ran it under valgrind.

Upvotes: 1

Related Questions