Segmentation fault when malloc/free appear in loop in C


I have a program that basically looks like:

    typedef struct cpl_def
            int A;
            int B;
            int OK; 
            struct cpls *link;  

        int main(void)
            int n1, n2;
            int num = 300; /* say */
            int *a;
            a = NULL;
            int *apt;

            int *b;
            b = NULL;
            int *bpt;

            cpls *cplptr; 
            cplptr = NULL; 

                int i, j;
                for (i=0; i < 2000; i++) 

                    if (i == 0)
                        cplptr = (cpls *) malloc(num*sizeof(cpls) ); /* create the structure */ 
                    ...operations on cplptr ...  */  

               ...determine I need a subset of size n1 (a positive integer of size n1 which changes during the loop) entries from cplptr ...  */

                 n1 = FOO2(cplptr);
                 n2 = FOO3(cplptr);

               ...figure out the values of A, B for additional n2 entries into cplptr ...
    cplptr2 = (cpls *) malloc(n2*sizeof(cpls) ); /* a second structure to store additional entries */
            /* .... operations on cplptr2 ...*/

    /* ...copy subset of n1 entries from cplptr into dynamically allocated arrays a,b of size n1... */  

            a = malloc(n1 * sizeof(int));
            apt = &a[0];

            b = malloc(n1 * sizeof(int));
            bpt = &b[0];

            for (j=0; j < num; j++)
                 if (cplptr[j].OK==1)
                            (*apt++) = cplptr[j].a;
                            (*bpt++) = cplptr[j].b;
               free(cplptr); /* free the first structure */

               cplptr = (cpls *) malloc((n1+n2)*sizeof(cpls) ); /* redeclare the first structure to reflect the proper sizes */

               for (j = 0; j < n1; j++) /* transfer a subset of size n1 to the first structure */
                       cplptr[j].a = a[j];
                       cplptr[j].b = b[j];
                       cplptr[j].OK = 1;
               for (j = n1; j < n1 + n2; j++) /* transfer things to the first structure */
                       cplptr[j].a = cplptr2[j].a;
                       cplptr[j].b = cplptr2[j].b;
                       cplptr[j].OK = cplptr2[j].OK;


               free(cplptr2); /* free the second structure */
             } /* End iteration i
    } /* End main() */

This is just the skeletal form but it hopefully provides enough of a picture. ANyhow it generally runs fine, but for some values of n1, n2, the free(cplptr) seems to cause a segmentation fault. It's only called once, and I check the address after the malloc() call to cplptr and before the corresponding free() for cplptr.

cplptr = (cpls *) malloc(num*sizeof(cpls) );
printf("fine to this %p\n", &cplptr[0]);
printf("fine to this %p\n", &cplptr[0]);
free(cplptr) <- segmentation fault happens here.

The addresses match, meaning free() should be freeing what it's supposed to, right??
gdb gives
Program received signal SIGSEGV, Segmentation fault.
0xb7ce179b in ?? () from /lib/tls/i686/cmov/
and step
Cannot find bounds of current function

Is there another way to implement something like that avoids the segmentation faults?

Thanks a million for your suggestions!
Any idea what's going on??

Best Solution

If you're hitting a crash on free(), this is most likely due to heap corruption - you are writing beyond the end of an allocated block of memory, freeing a pointer twice, or similar.

Valgrind is a great tool to debug these sort of issues on Linux.

Related Question