Reputation: 25
I'm having a problem with the following code compiles without errors, but in execution the error comes 'Double free or corruption (fasttop)'
void copyNoRepeat (int * v1, int tam1, int * v2, int * tam2_ptr)
{
int i, j;
int tam = * tam2_ptr // 0
for (i = 0; i <tam1; i ++) // 1
{
for (j = 0; j <tam; j ++) // 2
{
if (V1 [i] == v2 [j]) // 3
{
break;
}
}
if (j == tam) // 4
{
tam ++; // 5
v2 = (int *) realloc (v2, (tam + 1) * sizeof (int)); // 6
V1 [i] = v2 [j];
}
}
* Tam2_ptr = tam;
}
It crossed my mind that I was trying to do something that the compiler does not accept.
Before proceeding, a brief explanation of the code and my implementation of the function. I have a vector (v1) with repeated values and want to copy, through the function 'copyNoRepeat', only one number each for the other vector (v2) that is allocated dynamically. Example:
v1 = [11,8,15,19,19,2,11,18,15,5]
v2 = [11,8,15,19,2,18,5]
(Numbers repeated 11,19,15, were not copied to v2)
In implementing the function 'copyNoRepeat' I can not use realloc to allocate more 4 bytes of space to store a number in v2, this results in "Double free or corruption (fasttop)." I wonder why?
I wrote another code to test if the problem was to increase the tam // 2, as I did in // 5, but there is no problem with that, I wrote in another file only this stretch and it works perfectly.
Another detail that I noticed is that just removing the line tam ++ // of 5, the error message becomes 'segmentation fault'. If you remove the // line 6 with realloc, the algorithm runs as expected copying only unique, but appears the error: 'free (): invalid next size (fast)', I realized that it saves the values in subsequent memory locations, but in free time to do it is not aware that memory was allocated for this data.
----------------ALL CODE-------------------
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void geraValores(int v1[],int tam1,int limInf, int limSup);
void imprimeVetor(int v1[],int tam1);
void copiaValorsemrepetir(int *v1, int tam1, int *v2, int *tam2_ptr);
void checaValores(int *v1,int tam1, int *v2, int tam2);
int main (void)
{
int limInf = 0;
int limSup = 20;
int tam1 = 10;
int v1[tam1];
int tam2=0;
int *tam2_ptr = NULL;
tam2_ptr = &tam2;
int *v2;
v2=(int*)malloc(tam2*sizeof(int));
if(v2 == NULL)
{
printf("Erro! Memória não alocada.");
exit(0);
}
geraValores(v1,tam1,limInf,limSup);
imprimeVetor(v1,tam1);
//printf("Antes da func copia=%d\n",tam2);
copiaValorsemrepetir(v1,tam1,v2,tam2_ptr);
//printf("depois da func copia=%d\n",tam2);
imprimeVetor(v2,tam2);
free(v2);
}
void copiaValorsemrepetir(int *v1, int tam1, int *v2, int *tam2_ptr)
{
int i,j;
int tam = *tam2_ptr;
for(i=0; i<tam1;i++)
{
for(j=0;j<tam;j++)
{
if(v1[i]==v2[j])
{
break;
}
}
if(j == tam)
{
tam++;
//v2 = (int*)realloc( v2, tam*sizeof(int) );
v2[j] = v1[i];
}
}
*tam2_ptr = tam;
}
void geraValores(int v1[],int tam1,int limInf, int limSup)
{
srand( (unsigned)time(NULL) );
int j,k;
for(j=0; j<tam1; j++)
{
v1[j] = limInf + rand() % limSup;
}
}
void imprimeVetor(int v1[],int tam1)
{
printf("Vetor:\n");
int i;
for(i=0; i<tam1; i++)
{
printf("%d|", v1[i]);
}
printf("\n");
}
Upvotes: 1
Views: 101
Reputation: 34829
The problem is that v2
in function copiaValorsemrepetir
is not the same variable as v2
in main
. There are two variables, which I'm going to call v2func
and v2main
. v2func
is the copy used in function copiaValorsemrepetir
. v2main
is the copy that is in main
.
When you call realloc
to change v2func
, realloc
frees the memory that v2main
points to, and provides a new pointer that is stored in v2func
. When copiaValorsemrepetir
returns, the memory that v2func
points to is lost (resulting in a memory leak).
The pointer in main
still has its original value, which points to nothing. Therefore, the call to imprimeVetor
is using a bad pointer, which could result in a segfault. And the line free(v2)
attempts to free memory that has already been freed. That's why the code generates a "double free" error message.
To fix the problem, change the function call in main
to update v2
v2 = copiaValorsemrepetir(v1,tam1,v2,tam2_ptr);
And change the function so that it returns the new pointer to main
int *copiaValorsemrepetir(int *v1, int tam1, int *v2, int *tam2_ptr)
{
...
*tam2_ptr = tam;
return v2;
}
Upvotes: 2
Reputation: 6563
v2
must be double pointer int ** v2
because after realloc
the new value of the pointer must be returned to the calling function (where it is free
-d).
Upvotes: 0