动态分配的数组上的未定义行为(分段错误)

时间:2017-06-07 02:26:24

标签: c dynamic segmentation-fault undefined heap-memory

该程序计算形式的斐波那契数列:t1,t2,t3 = t1 + t ^ 2,t4 = t2 + t3 ^ 2 ...

要计算的系列中需要三个输入t1,t2和第n个数字。

由于数字呈指数级增长,我使用数组来显示和执行大数字的操作。

问题:

我遇到了一些奇怪的错误:

bsquare[j] = *b[j]

使用输入0 1 8重新创建错误,它适用于输入到7。我也尝试使用gdb进行调试,但调试器显示当我使用p ** b @ 50和bn似乎也可以访问内存有效。我错过了一些未定义的行为吗?

代码

#include<stdio.h>
#include<stdlib.h>

int carry = 0;
int fibo( int **a, int **b, int **c, int n);
void sum(int *a, int *b, int *c, int *an, int *bn, int *cn);
void sqr(int *b, int *bn);
int main()
{   

    int *a, *b, *c;
    int t1, t2, n, i, bn;

    scanf("%d%d%d",&t1, &t2,&n);

    a = (int * ) calloc(100, sizeof(int));
    b = (int * ) calloc(100, sizeof(int));
    c = (int * ) calloc(100, sizeof(int));
    a[0] = t1; b[0] = t2;

    bn = fibo(&a,&b,&c,n);

    printf("\nNumber is: ");
    for(i = bn-1; i>=0; i--)
    printf("%d",b[i]);

    free(a);free(b);free(c);
    return 0;
}
void sqr(int *b, int *bn)
{   int c[50] = {0};
    int i , j ,k = 0;
    int temp = 0;
    for(i = 0; i < *bn; i++)
    {    k = i;
        carry = 0;
        for(j = 0; j < *bn ;j++)
        {
            temp = c[k] + b[i] * b[j] + carry;
            if(temp>9)
            {
                carry = temp / 10;
                c[k] = temp % 10;

            }
            else
            {
                c[k] =  temp;
                carry = 0;
            }
            k++;
        }
        if(carry !=0)
        {c[k++] = carry;
        }

    }

    for(i = 0; i<k; i++)
    {   
        b[i] = c[i];

    }

    *bn = k;



}

void sum(int *a, int *b, int *c, int *an, int *bn, int *cn)
{

    int i=0 , j ,k = 0;
    int *temp1;
    int temp = 0;
    for(j=0; j<*cn; j++)
     c[j] = 0;
            *cn = 0;
     carry = 0;
    for(; i < *bn && i < *an; i++)
    {   
        temp = a[i] + b[i] + carry;

        if(temp>9)
        {
            c[k] = temp % 10;
            carry = temp/10;

        }
        else
        {
            c[k] = temp;
            carry = 0;
        }
        k++;
    }

    while(i<*an)
    {
        temp = carry + a[i];
        if(temp>9)
        {
            c[k] = temp % 10;
            carry = temp/10;

        }
        else
        {
            c[k] = temp;
            carry = 0;
        }
        k++;i++;
    }

    while(i<*bn)
    {
        temp = carry + b[i];
        if(temp>9)
        {
            c[k] = temp % 10;
            carry = temp/10;

        }
        else
        {
            c[k] = temp;
            carry = 0;
        }
        k++;i++;
    }
    if(carry!=0)
    {
        c[k++] = carry;
    }

    *cn = k;




}

int fibo( int **a, int **b, int **c, int n)
{
    int i, j,*tmpdb;

    int bn = 1, an = 1, cn = 0, bsn = 0, temp;
    int bsquare[100] = {0};

    for(i = 3; i<= n; i++)
        {   
            for(j = 0; j<bn; j++)
                bsquare[j] = *b[j];

            bsn = bn;

            sqr(bsquare,&bsn);
            sum(*a,bsquare,*c,&an,&bsn,&cn);

            tmpdb = *a;
            *a = *b;
            *b = *c;
            *c = tmpdb;

            temp = an;
            an = bn;
            bn = cn;
            cn = temp;



        }
    return bn;

}

2 个答案:

答案 0 :(得分:1)

正如BLUEPIXY的评论所指出的那样,*b[j]应该更改为(*b)[j],因为你已经将b作为双指针传递给fibo,b存储了来自main函数的指针变量的地址它反过来存储数组存在的地址。

*b[j]将被评估为*(*(b+j))存储在b中的地址有效(来自main的指针变量b的地址),b+j将您带到无效地址,访问它可能导致段故障

你需要来自数组的第j个元素,其地址存储在b中,正确的访问方式是(*b)[j]其中(* b)获取数组的基地址

答案 1 :(得分:0)

您没有像预期的那样更新b[]值。您已存储b[0]=t2,之后不会在其他地方更新。所以你的程序在b[1]给出了分段错误。所以我会说只更新b[]数组,你就可以了。并且请练习在您的代码中提供一点评论,这很难阅读。