opisthofulax
opisthofulax

Reputation: 551

Freeing array of struct of array and reusing it cause malloc: Incorrect checksum for freed object

I have the following program which tries to initialise array anet of type netw with groups of M_/N_ equal values, so that the array s variable looks like 0 0 0 0 ... 1 1 1 1 ... M_ M_ M_ M_. At the same time a counter of how many times element i of anet has been in state M_ is implemented an array n_i inside struct anet. SN_ is the number of simulation i want to repeat, so that for every set of the parameters M_, N_, T_, L_, C_ which are read from file there will be a for loop executing the initialisation of the array SN_ times.

#include<stdio.h>
#include<stdlib.h>
// 
size_t i, j, sm;
int M_, SN_, N_, T_;
double L_, C_;
// 
struct netw {
    int s;
    unsigned long long *n_i;
} *anet;
// 
void freeNet(struct netw *arr);
struct netw *initNet(size_t l);
// 
int main() {
    FILE *f_in;
    f_in = fopen("tmp", "r");
    fscanf(f_in, "%*[^\n]");
    while(fscanf(f_in, "%d %d %d %lf %lf %d", &T_, &N_, &M_, &L_, &C_, &SN_)
        != EOF) {
            printf("%d %d %d %lf %lf %d\n", T_, N_, M_, L_, C_, SN_);
        for (sm = 0; sm < SN_; sm++) {
            anet = initNet(N_);
            freeNet(anet);
        }
    }
    fclose(f_in);
}
void freeNet(struct netw *arr) {
    for (i = 0; i < N_; i++) {
        free(arr[i].n_i);
    }
    free(arr);
}
struct netw *initNet(size_t l) {
    struct netw *arr = calloc(l, sizeof(struct netw));
    int NM_ = (int) l/M_;
    for (i = 0; i < l; i+=NM_) {
        if (i < l - NM_) {
            printf(" i < l - NM_ %zu", i);
            for (j = i; j < i+NM_; j++) {
                printf("\t%zu_1", j);
                arr[j].n_i = calloc(M_, sizeof(unsigned long long));
                arr[j].s = (int) i/NM_;
                printf("\t%d", arr[j].s);
                arr[j].n_i[arr[j].s]++;
                printf("\t%zu_2\n", j);
            }
        } else {
            for (j = i; j < l; j++) {
                printf("\t%zu_1", j);
                arr[j].n_i = calloc(M_, sizeof(unsigned long long));
                arr[j].s = (int) i/NM_;
                printf("\t%d", arr[j].s);
                arr[j].n_i[arr[j].s]++;
                printf("\t%zu_2\n", j);
            }
            printf("i =l - NM_ %zu\n", i);
        }
    }
    return arr;
}

values of M_, SN_, N_, T_, L_, C_ are read form a file tmp which looks like

# T_    N_      M_      L_      C_      Nsim
500 1000 100 2.00e-01 1.000 10
500 1000 300 2.00e-01 1.000 10
500 1000 500 2.00e-01 1.000 10
500 1000 800 2.00e-01 1.000 10
500 1000 1000 2.00e-01 1.000 10
500 1000 100 2.00e-01 1.100 10
500 1000 300 2.00e-01 1.100 10
500 1000 500 2.00e-01 1.100 10
500 1000 800 2.00e-01 1.100 10
500 1000 1000 2.00e-01 1.100 10
500 1000 100 2.00e-01 1.500 10
500 1000 300 2.00e-01 1.500 10
500 1000 500 2.00e-01 1.500 10
500 1000 800 2.00e-01 1.500 10
500 1000 1000 2.00e-01 1.500 10

Now when executing this code it always get stuck at the second row of values with the following error:

help_malloc.x(68852,0x10f238dc0) malloc: Incorrect checksum for freed object 0x7fa79c264c00: probably modified after being freed.
Corrupt value: 0x1
help_malloc.x(68852,0x10f238dc0) malloc: *** set a breakpoint in malloc_error_break to debug
zsh: abort      ./help_malloc.x

I tried some basic debugging by putting some printf and I noticed that the first two sm=0,1 run no problem arises and one get the output

 i < l - NM_ 996    996_1   332 996_2
    997_1   332 997_2
    998_1   332 998_2
    999_1   333 999_2
i =l - NM_ 999

so that I know that the whole array was successfully initialised, but the third time (is it a case that 3 = NM_ for N_ = 1000 and M_ = 300?) sm loop is executed the code stops before i=999:

i < l - NM_ 957 957_1   319 957_2
    958_1   319 958_2
    959_1   319 959_2
 i < l - NM_ 960    960_1   320 960_2
help_malloc.x(68872,0x119174dc0) malloc: Incorrect checksum for freed object 0x7fca85882e00: probably modified after being freed.
Corrupt value: 0x1
help_malloc.x(68872,0x119174dc0) malloc: *** set a breakpoint in malloc_error_break to debug
    961_1zsh: abort      ./help_malloc.x

What am I doing wrong and why doesn't the code stop before if there is a wrong usage of allocation and freeing of memory?

Upvotes: 1

Views: 67

Answers (1)

anastaciu
anastaciu

Reputation: 23822

At glance, my guess is undefined behavior by way of access to unallocated memory.

Running your code, it seems that the problem lies int the calloc call arr[j].n_i = calloc(M_, sizeof(unsigned long long));.

In a quick debug using arr[j].n_i = calloc(M_, sizeof(unsigned long long) + 1); seems to fixes the issue, but you may need a more comprehensive solution. Likely adjusting your cycles so that there is no out of bounds access.

P.S.: Your code crashes valgrind, so congrats on that ;).

Upvotes: 1

Related Questions