在函数

时间:2016-09-22 18:19:30

标签: c

我遇到以下代码编译时出现问题而没有错误,但在执行过程中出现错误' 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;
}

我突然想到我正在尝试做一些编译器不接受的事情。

在继续之前,简要说明代码和我对函数的实现。我有一个带有重复值的向量(v1),并希望通过函数“copyNoRepeat”复制每个动态分配的另一个向量(v2)中只有一个数字。例如:

v1 = [11,8,15,19,19,2,11,18,15,5]

v2 = [11,8,15,19,2,18,5]

(数字重复11,19,15,未复制到v2)

实施功能&#39; copyNoRepeat&#39;我不能使用realloc分配更多4个字节的空间来存储v2中的数字,这会导致&#34; Double free或者腐败(fasttop)。&#34;我想知道为什么?

我编写了另一个代码来测试问题是否是为了增加tam // 2,就像我在// 5中所做的那样,但是没有问题,我在另一个文件中只写了这一段并且它完美地工作。

我注意到的另一个细节是,只删除行tam ++ //为5,错误消息变为&#39; segmentation fault&#39; 。如果使用realloc删除//第6行,算法将按预期运行,仅复制唯一,但会出现错误:&#39; free():无效的下一个尺寸(快)&#39; ,我意识到它会将值保存在后续的内存位置,但是在空闲时间这样做并不知道是为这些数据分配了内存。

----------------所有代码-------------------

#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");
}

2 个答案:

答案 0 :(得分:2)

问题在于,v2函数中的copiaValorsemrepetirv2main的变量不同。有两个变量,我将调用v2funcv2mainv2func是函数copiaValorsemrepetir中使用的副本。 v2mainmain中的副本。

当您致电realloc更改v2func时,realloc会释放v2main指向的内存,并提供存储在v2func中的新指针。当copiaValorsemrepetir返回时,v2func指向的内存将丢失(导致内存泄漏)。

main中的指针仍然具有原始值,指向任何内容。因此,对imprimeVetor的调用使用了错误的指针,这可能会导致段错误。行free(v2)尝试释放已释放的内存。这就是代码生成&#34; double free&#34; 错误消息的原因。

要解决此问题,请更改main中的函数调用以更新v2

v2 = copiaValorsemrepetir(v1,tam1,v2,tam2_ptr);

更改函数,使其返回指向main

的新指针
int *copiaValorsemrepetir(int *v1, int tam1, int *v2, int *tam2_ptr)
{
    ...

    *tam2_ptr = tam;
    return v2;
}

答案 1 :(得分:0)

v2必须是双指针int ** v2,因为在realloc之后必须将指针的新值返回给调用函数(它是free - d)。