Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 存储mpz_t的地址并传递指针_C_Pointers_Scope_Gmp_Nan Boxing - Fatal编程技术网

C 存储mpz_t的地址并传递指针

C 存储mpz_t的地址并传递指针,c,pointers,scope,gmp,nan-boxing,C,Pointers,Scope,Gmp,Nan Boxing,据我所知,mpz\u t只不过是一个单项目数组 根据: 这意味着,给定C处理数组的方式,mpz_t本身实际上就是一个指针(指向单元素数组的第一个元素) 现在,假设我在一个函数中创建一个新的mpz\u t,将指针“box”在一个无符号的long中并返回,然后。。。混乱。(因为,我猜,指针不再有效?) 理论上,我能使它工作的唯一方法是将mpz\u t声明移到函数体之外(基本上,使其成为全局的) 还有其他更明智的想法吗 最小示例: typedef uint64_t Value; #define a

据我所知,
mpz\u t
只不过是一个单项目数组

根据:

这意味着,给定C处理数组的方式,mpz_t本身实际上就是一个指针(指向单元素数组的第一个元素)

现在,假设我在一个函数中创建一个新的
mpz\u t
,将指针“box”在一个无符号的long中并返回,然后。。。混乱。(因为,我猜,指针不再有效?)

理论上,我能使它工作的唯一方法是将
mpz\u t
声明移到函数体之外(基本上,使其成为全局的)

还有其他更明智的想法吗


最小示例:

typedef uint64_t Value;

#define addWillOverflow(x,y,z) __builtin_sadd_overflow(x,y,z)

#define BITFIELD 56

#define MASK(x) ((Value)(x) << BITFIELD)
#define UNMASK  0x00FFFFFFFFFFFFFF

#define toI(v)  ( (Value)(v & 0xFFFFFFFFu) | MASK(IV) )
#define toG(v)  ( (Value)(v) | MASK(GV) )
#define GG(v)   ( (v & UNMASK) )

Value addNumbers(int a, int b) {
    Int32 res;
    if (addWillOverflow(a,b,&res)) {
        printf("overflow\n");
        mpz_t ret;
        mpz_init_set_si(ret,a);
        mpz_add_ui(ret,ret,b);
        return toG(ret);
    }
    else {
        printf("normal addition\n");
        return toI(res);
    }
}

int main(int argc, char** argv) {

    printf("3 + 5 = ");
    printLnValue(addNumbers(1,2));

    printf("2b + 2b = ");
    Value a = addNumbers(2000000000,2000000000);
    printLnValue(a);
    printf("pointer: %p\n",GG(a));

    Value b = addNumbers(2100000000,2011111111);
    printLnValue(b);
    printf("pointer: %p\n",GG(b));
}
3 + 5 = normal addition
3
2b + 2b = overflow
4000000000
pointer: 0x7ffee5b95630
overflow
4111111111
pointer: 0x7ffee5b95630
如您所见,返回的指针是。。。相同的。虽然我期待一个不同的


第2次更新

我目前正在考虑这样做:(我会看看它是如何运行的,然后自己把它作为一个解决方案发布)


向我们展示您的实际代码。@JohnZwinck我将尝试制作一个最小的示例。@JohnZwinck我刚刚在其输出中添加了一些示例代码,以了解我的问题所在。为什么您希望使用不同的地址
ret
显然是一个局部变量(即堆栈分配)。无论如何,
malloc
解决方案是正确的。您可能会对中的注释感兴趣。您的目标是返回一个mpz_t,只需看看GMP是如何实现的(例如mpz_添加)。或者移动到C++,使用MPZL类,就像你使用int一样,并且担心其他的东西。
3 + 5 = normal addition
3
2b + 2b = overflow
4000000000
pointer: 0x7ffee5b95630
overflow
4111111111
pointer: 0x7ffee5b95630
    mpz_t* ret = malloc(sizeof(mpz_t));
    mpz_init_set_si(*ret,a);
    mpz_add_ui(*ret,*ret,b);
    return toG(ret);