#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
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:
NULL
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.