clearner
clearner

Reputation: 25

Weird error when using malloc in a function

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

Answers (2)

user3386109
user3386109

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

i486
i486

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

Related Questions