使用指针添加时出现glibc错误

时间:2011-11-23 04:51:27

标签: c pointers malloc glibc realloc

我在终端编译程序时遇到以下错误:

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

2 个答案:

答案 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使用,但我建议使用操作系统选择的包管理方法来获取它,如果可能的话。