我在终端编译程序时遇到以下错误:
*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x089660a0 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x6ebc2)[0xb7621bc2]
/lib/i386-linux-gnu/libc.so.6(+0x6f862)[0xb7622862]
/lib/i386-linux-gnu/libc.so.6(cfree+0x6d)[0xb762594d]
./a.out[0x8048668] ./a.out[0x8048fa3]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb75cc113]
./a.out[0x80484c1]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 08:06 1835029 /home/fasih/poly/a.out
0804a000-0804b000 r--p 00001000 08:06 1835029 /home/fasih/poly/a.out
0804b000-0804c000 rw-p 00002000 08:06 1835029 /home/fasih/poly/a.out
08966000-08987000 rw-p 00000000 00:00 0 [heap]
b7400000-b7421000 rw-p 00000000 00:00 0
b7421000-b7500000 ---p 00000000 00:00 0
b757f000-b759b000 r-xp 00000000 08:06 4195258 /lib/i386-linux-gnu/libgcc_s.so.1
b759b000-b759c000 r--p 0001b000 08:06 4195258 /lib/i386-linux-gnu/libgcc_s.so.1
b759c000-b759d000 rw-p 0001c000 08:06 4195258 /lib/i386-linux-gnu/libgcc_s.so.1
b75b1000-b75b3000 rw-p 00000000 00:00 0
b75b3000-b7729000 r-xp 00000000 08:06 4195237 /lib/i386-linux-gnu/libc-2.13.so
b7729000-b772b000 r--p 00176000 08:06 4195237 /lib/i386-linux-gnu/libc-2.13.so
b772b000-b772c000 rw-p 00178000 08:06 4195237 /lib/i386-linux-gnu/libc-2.13.so
b772c000-b772f000 rw-p 00000000 00:00 0
b772f000-b7757000 r-xp 00000000 08:06 4195267 /lib/i386-linux-gnu/libm-2.13.so
b7757000-b7758000 r--p 00028000 08:06 4195267 /lib/i386-linux-gnu/libm-2.13.so
b7758000-b7759000 rw-p 00029000 08:06 4195267 /lib/i386-linux-gnu/libm-2.13.so
b776c000-b776f000 rw-p 00000000 00:00 0
b776f000-b7770000 r-xp 00000000 00:00 0 [vdso]
b7770000-b778e000 r-xp 00000000 08:06 4195224 /lib/i386-linux-gnu/ld-2.13.so
b778e000-b778f000 r--p 0001d000 08:06 4195224 /lib/i386-linux-gnu/ld-2.13.so
b778f000-b7790000 rw-p 0001e000 08:06 4195224 /lib/i386-linux-gnu/ld-2.13.so
bfed6000-bfef7000 rw-p 00000000 00:00 0 [stack] Aborted
这是我的代码,它似乎发生在polyAdd函数中,但我也得到一个断言失败的乘法,所以它可能都是?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#include "poly.h"
int polyDegree(struct poly *p)
{
return p->length-1;
}
struct poly *polyCreate()
{
struct poly *p = (struct poly *)malloc(sizeof(struct poly));
p->coeff=(double *)malloc(sizeof(double));
p->size=1;
p->length=0;
return p;
}
struct poly *polySetCoefficient (struct poly *p, int i, double value)
{
if(p == NULL)
return;
if(i>=p->size)
{
do
{
p->size = p->size*2;
}while(i>=p->size);
p->coeff = (double *)realloc(p->coeff, p->size*sizeof(double));
}
while(i >= p->length)
{
p->coeff[p->length] = 0;
p->length++;
}
p->coeff[i] = value;
return p;
}
struct poly *polyDelete(struct poly *p)
{
if (p){
free(p);}
return 0;
}
struct poly *polyCopy(struct poly *p)
{
struct poly *nP = polyCreate();
nP->size =p->size;
nP->length = p->length;
int i = 0;
for (i = 0; i<(nP->size);i++)
{
nP->coeff[i] = p->coeff[i];
}
return nP;
}
struct poly *polyAdd(struct poly *p0, struct poly *p1)
{
int i;
struct poly *pF = polyCreate();
if (p0->length > p1->length)
{
pF = polyCopy(p0);
for (i=0;i<p1->length;i++)
pF->coeff[i] += p1->coeff[i];
}
else if (p1->length >= p0->length)
{
pF = polyCopy(p1);
for (i=0;i<p0->length;i++)
pF->coeff[i] += p0->coeff[i];
}
return pF;
}
struct poly *polyPrime (struct poly *p)
{
struct poly *pF = polyCreate();
pF->size = p->size;
int i,j,k;
int n = p->size;
double a[n-1];
for (i = 1; i <=n;i++)
{
a[i-1] = i * p->coeff[i];
}
for (i = 0; i < n; i++)
{
pF->coeff[i] = a[i];
}
return pF;
}
struct poly *polyMultiply (struct poly *p0, struct poly *p1)
{
struct poly *product = polyCreate();
product->length = p0->length + p1->length - 1;
product->size = p0->size + p1->size;
product->coeff = (double *)malloc(product->size*sizeof(double));
int i,j;
for(i=0;i<product->length;i++)
product->coeff[i] = 0;
for(i=0;i<p0->length;i++)
for(j=0;j<p1->length;j++)
product->coeff[i+j] += p0->coeff[i] * p1->coeff[j];
return product;
}
double polyGetCoefficient(struct poly *p, int i)
{
double val =p->coeff[i];
return val;
}
int checkZero (double a[], int n)
{
int x = 0;
for (x = 0; x < n; x++)
{
if (a[x] != 0)
return 1;
}
return 0;
}
double polyEval(struct poly *p, double x)
{
int i,n;
double eval=0;
if (!p)
return 0;
if (p)
n = p->length;
if (n == 0)
return 0;
for (i = 0; i<=n;i++)
{
if (p->coeff[i] == 0)continue;
if (i == 0)eval += p->coeff[0];
else
eval += p->coeff[i]* pow (x,i);
}
return eval;
}
void polyPrint (struct poly *p)
{
int x=0,y,z;
int n;
n = p->size;
double a[p->size];
for (x = p->size; x >= 0; x--)
{
a[x] = p->coeff[x];
}
bool check,neg,zero = true;
if (!checkZero (a,n))
{
printf("0\n");
}
else{
for(x=(n-1);x>=0;x--)
{
check = false;
neg = false;
if (x < (n-1) && a[x+1] == 0 && a[x] != 0 && a[x] > 0 && !zero)
printf(" + ");
else if (x < (n-1) && a[x+1] == 0 && a[x] != 0 && a[x] < 0 && !zero)
{
printf (" - ");
a[x] = a[x] * -1.00;
}
if (a[x] == 0)
continue;
if (a[x] != 0.0&& x > 1)
{
if (a[x] == -1)printf("-x^%d",x);
else if (a[x] == 1)printf ("x^%d",x);
else
printf("%gx^%d",a[x],x);
check = true;zero = false;
}
else if (x == 1)
{
if (a[x] == 1)printf("x");
else
printf("%gx",a[x]);
check = true; zero = false;
}
else if (x == 0)
{
printf("%g",a[x]);
check = false; zero = false;
}
if (a[x-1] < 0 && x > 0){
printf (" - ");a[x-1] = a[x-1] * -1.00;}
else if (x > 0&& a[x-1] != 0)printf(" + ");
}
printf("\n");}
}
答案 0 :(得分:3)
这是一个错误:
for (i = 0; i<=n;i++)
{
if (p->coeff[i] == 0)continue;
if (i == 0)eval += p->coeff[0];
else
eval += p->coeff[i]* pow (x,i);
}
C中的数组索引从0
运行到n-1
; i<=n
将评估p->coeff[n]
,这是垃圾数据。 (这也是垃圾格式化 - 我建议通过indent(1)
运行整个程序; Linux内核使用indent(1)
参数:-npro -kr -i8 -ts8 -sob -l80 -ss -ncs -cp1 -il0
;我喜欢这些。)
这是同样的错误,形式略有不同:
n = p->size;
double a[p->size];
for (x = p->size; x >= 0; x--)
{
a[x] = p->coeff[x];
}
我希望p->size
是数组的 size ,而不是最大的数组下标。
这是一个不同的错误:
if (a[x] != 0.0&& x > 1)
{
在浮点算术中,0.0
很少等于0.0
,你可能会感到震惊。永远不要做这样的直接比较 - 相反,检查差异是否接近于零,你可以将其称为零。 (这里没有关于0.0
的信息 - 需要仔细处理全面的浮点比较。)
答案 1 :(得分:2)
在这种情况下,值得通过valgrind运行你的程序:
valgrind ./your_program
这可能会或多或少准确地确定发生任何错误写入的位置。修复你找到的东西,再次通过valgrind运行并检查你是否已经拥有它们。请注意,尽管valgrind不会,至少在我上次检查时,会警告您对堆栈分配的数组的访问越界。
Valgrind可以作为源here使用,但我建议使用操作系统选择的包管理方法来获取它,如果可能的话。