这与incorrect pointer value passed to a C function类似,但似乎没有答案。
我有一个名为bigint
的结构,其中包含字段char sign
,size_t len
和uint32_t *val
。 bigint
由bigint_init()
函数初始化,该函数为uint32_t
数组分配一些内存,设置默认值等。
我有一个功能void bigint_subtract(bigint a, bigint b, bigint *diff)
,可以a-b
存储diff
。我之前测试过这个函数,如下所示:
bigint test = bigint_inithex("4567890987654345678987654adbfcaedcfaaebfc625213");
bigint test2 = bigint_inithex("acbefabedfc13271723976aebdfcabefc12837618237");
bigint diff = bigint_init();
bigint_subtract(test,test2,&diff);
printf("0x%s - 0x%s == 0x%s\n\n",bigint_tohex(test), bigint_tohex(test2),bigint_tohex(diff));
在众多其他边缘情况测试,不同长度等测试中。所有测试都检查出来。
现在,我在另一个函数中,void bigint_egcd(bigint a, bigint b, bigint c, bigint *x, bigint *y);
这只是扩展的欧几里德算法。在扩展欧几里德算法的主循环中,我有以下代码:
bigint rold, rnew, q, r, ...;
rold = bigint_init();
bigint_cpy(&rold, a);
rnew = bigint_init();
bigint_cpy(&rnew, b);
...[more initializations, etc.]
while(!bigint_isval(rnew, 0)){
bigint_divide(rold,rnew,&q,&r);
bigint_cpy(&tmp1, rnew);
bigint_multiply(q,rnew,&tmp2);
bigint_subtract(rold,tmp2,&rnew);
bigint_cpy(&rold, tmp1);
....
}
事情出错了,所以我做了一些调试,无法解决任何问题,所以我开始添加printfs。以下是它现在的样子:
while(!bigint_isval(rnew, 0)){
bigint_divide(rold,rnew,&q,&r);
printf("\t%s = %s * %s + %s\n", bigint_tohex(rold), bigint_tohex(rnew), bigint_tohex(q), bigint_tohex(r));fflush(stdout);
bigint_cpy(&tmp1, rnew);
printf("\tupdated r = %s - %s * %s = ", bigint_tohex(rold), bigint_tohex(q), bigint_tohex(rnew));fflush(stdout);
bigint_multiply(q,rnew,&tmp2);
printf("%s - %s = (%p) ", bigint_tohex(rold), bigint_tohex(tmp2), &rnew);fflush(stdout);
bigint_subtract(rold,tmp2,&rnew);
printf("%s at address %p\n", bigint_tohex(rnew),&rnew);fflush(stdout);
bigint_cpy(&rold, tmp1);
在bigint_subtract
的开头,我添加了以下printf:
void bigint_subtract(bigint a, bigint b, bigint *diff){
printf("BIGINT_SUBTRACT diff address is %p\n", diff);fflush(stdout);
....
所以我发现bigint_subtract
收到的地址与bigint_egcd
中传递给它的地址不一样。同时,减法实际上是正确的,它只是存储一些随机地址,而不是更新存储在rnew
的值。
与此同时,循环后面的完全相同的代码,t
和s
代替其r
对应代码,不会出现此行为 - 所有地址都正确传递。 rnew
和rold
已在bigint_egcd
的顶部正确初始化,其方式与t
和s
对应方式完全相同。
简而言之,我有一个变量bar1
。我将&bar1
传递给foo(type *var)
,但不知何故,只有在foo
内,它才会成为其他内容。是什么赋予了?什么样的错误可能导致这种情况发生?
修改
这是bigint_tohex
:
static const char *BII_HEX="0123456789abcdef";
char *bigint_tohex(bigint a){
char *hex = calloc((a.len<<3) + 1,sizeof(char));
uint8_t j;
for(size_t i=0; i<a.len; i++){
for(j=0; j<8; j++){
hex[ (i<<3) + j ] = BII_HEX[(a.val[i] >> ((7-j)<<2)) & 0xF];
}
}
hex[a.len<<3] = 0;
//any leading 0s should be removed:
int i=0;
while(hex[i]=='0' && hex[i+1]!=0) ++i;
memmove(hex,hex+i,strlen(hex)+1-i);
if(a.sign == BII_NEG){
hex = realloc(hex, (strlen(hex)+1)*sizeof(char));
memmove(hex+1,hex,strlen(hex)+1);
hex[0]='-';
}
return hex;
}