我遇到以下代码编译时出现问题而没有错误,但在执行过程中出现错误' 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");
}
答案 0 :(得分:2)
问题在于,v2
函数中的copiaValorsemrepetir
与v2
中main
的变量不同。有两个变量,我将调用v2func
和v2main
。 v2func
是函数copiaValorsemrepetir
中使用的副本。 v2main
是main
中的副本。
当您致电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)。