此程序计算以下形式的斐波那契数列: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/