Okeefe Niemann
Okeefe Niemann

Reputation: 91

Segmentation Fault (Malloc/Free in a Loop)

I've been revisiting the C language and am having trouble freeing up memory after use in my program:

    int tvalue = 2;
    while (smult == 0) {
        int * tvaluearray = calloc(allnum, sizeof(int));    
        tvaluearray = frequencyArray(tvalue, allnum, tvaluearray);
        printf("tvalue = %d\n", tvalue);    
        //compare each index of the tvaluearray and the first array
        for (int j = 0; j < allnum; j++) {
//          printf("tvaluearray[%d]=%d >= firstarray[%d]=%d\n", j, tvaluearray[j], j, firstarray[j]);
            if (tvaluearray[j] < firstarray[j]) {
            //  printf("Found the false statement\n");
                break;
            }
            else if ( (j+1) == allnum ){
                smult = 1;
//              printf("Made it to else if! smult = %d\n", smult);
            }
        }
        free(tvaluearray);
        ++tvalue;
    }

The frequencyArray function is shown below:

int * frequencyArray (int target, int allnum, int targetarray[]) {
    int divisor = 2;

    for (int i = 0; i < allnum; i++)
        targetarray[i] = 0;
    //find the common factor frequency of the given number
    while (target > 1) {
        if (target % divisor == 0) {
            targetarray[divisor] += 1;
            target /= divisor;
        }
        else
            ++divisor;
    }


    return targetarray;
}

Having played around with this a bit, I've tried the following with different results:

1) removing the free of targetarray:

tvalue = 1306 --> segfault

2) including the free(targetarray):

tvalue = 29 free(): invalid next size (fast) Aborted (core dumped)

3) including free(targetarray) AND allocating 4*sizeof(int) for the tvaluearray calloc as opposed to just int:

tvalue = 31468 --> segfault

The third test had me changing the allocated space for the array with varying results before my program runs into the segmentation fault error. This has me thinking that there's an issue with the way I'm allocating space, but I think it just might be a little bit beyond my current understanding. Do any of y'all see where I may be going wrong?

Upvotes: 1

Views: 289

Answers (1)

VillageTech
VillageTech

Reputation: 1995

In frequencyArray() function you have a loop:

while (target > 1) {
    if (target % divisor == 0) {
        targetarray[divisor] += 1;
        target /= divisor;
    }
    else
        ++divisor;
}

where divisor is used as index of your targetarray[]. I can't see here any formal bounds for maximum value of divisor - it seems that it can grow over maximum allowed value (equal allnum - 1), so the memory outside targetarray[] can be overwritten resulting in memory corruption/segmentation fault. You should check in each iteration that divisor < allnum .

Unfortunately, I don't know the context of your code, so can't propose any appropiate solution here. Probably it should look like:

while (target > 1) {
    if (target % divisor == 0) {

        // 'fuse' ;)
        if (divisor >= allnum) {
           // place here the code needed to solve the problem or break to exit from loop
        }
        // end of 'fuse'

        targetarray[divisor] += 1;
        target /= divisor;
    }
    else
        ++divisor;
}

Upvotes: 0

Related Questions