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

标签 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;

}

最佳答案

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

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

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

关于c - 动态分配数组的未定义行为(段错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44402493/

相关文章:

c - 错误 : comparison between pointer and integer ('int' and 'string' (aka 'char *' ))

c - 文字类型 : 0x1ull vs 0x1llu

c - 替换 C 字符字符串中的字符串(strreplace,无 sprintf)

c - 在互斥锁内调用 sleep() 有什么缺点?

php - 如何根据最多 17 个不同的变量查询表?

Linq To Sql - 动态排序 - Case When

javascript - 欧拉项目#345 : Max sum matrix with unique path

c - 我在执行代码时收到段错误。有什么问题吗?

尝试解析 CORBA 引用时出现 C++ 段错误

c++ - 调用函数时出现段错误