Search code examples
cdynamic-arrays

Program terminated with signal SIGABRT, Aborted


#include<stdio.h>
#include<stdlib.h>
int main(void)
{
    int **seqList, n, q;
    scanf("%d %d", &n, &q);
    seqList = (int**)malloc(n * sizeof(int*));
    int *l_sub_seq = (int*)calloc(n, sizeof(int));//length of subsequences of all sequences                                              
    int lastAnswer = 0;

    while(q--)
    {
        int type, x, y, i;
        scanf("%d %d %d", &type, &x, &y);
        i = (x^lastAnswer) % n;
        switch(type)
        {
            case 1:
            l_sub_seq[i]++;
            seqList[i] = (int*)realloc(seqList[i], sizeof(int)*l_sub_seq[i]);
            seqList[i][l_sub_seq[i] - 1] = y;
            break;

            case 2:
            lastAnswer = seqList[i][y%l_sub_seq[i]];
            printf("\n");
            break;
        }
    }
    for(int i = 0; i < n; i++)
        free(seqList[i]);
    free(seqList);

    for(int i = 0; i < n; i++)
        free(l_sub_seq);

    return 0;
}

Compiler message:

free(): double free detected in tcache 2
Reading symbols from Solution...done.
[New LWP 335079]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./Solution'.
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50


Solution

  • Your code potentially invokes undefined behavior in at least one location, and definitely invokes it in another.

    realloc allows an input pointer value that is either:

    1. NULL
    2. A value returned from malloc, calloc, or realloc

    Your initial allocation of seqList :

    seqList = (int**)malloc(n * sizeof(int*));
    

    creates a sequence of pointers to int. Those pointers are indeterminate (they have no determined value, be it NULL or any other valid value) that can be passed to realloc. Therefore, later in code when you do this:

    seqList[i] = (int*)realloc(seqList[i], sizeof(int)*l_sub_seq[i]);
    here ======================^^^^^^^^^^
    

    You're invoke undefined behavior. You can address this by ensuring your intial array contents are null-populated, either by using zero-filling calloc (easiest), or by loop, memset, whatever.

    Later, at the end of your program, you do this:

    for (int i = 0; i < n; i++)
        free(l_sub_seq);
    

    That's nonsense. l_sub_seq was allocated with:

    int *l_sub_seq = (int*)calloc(n, sizeof(int));
    

    It should be free'd once, not in some loop, repeatedly passing the same pointer value over and over to free.

    free(l_sub_seq); // no loop.
    

    Whether the rest of your program "works" is up to you to decide, but the reasons for your termination woes are likely from the issues covered above.