【问题标题】:Define struct in the heap with different sizes在堆中定义不同大小的struct
【发布时间】:2017-07-30 07:53:38
【问题描述】:

我正在尝试实现一个 bigInt 库。我一直在检查其他库,如 GMPttmahtlibtommath,但它们中的任何一个都满足项目的要求(因为许可证,因为它们只使用堆栈等)

我将遵循 libtommath 的方法(非常有据可查,并且全部用 C 编写),但我希望所有内容都存储在堆中。 libtommath 在类似这样的结构中实现了 bigInt:

typedef struct  {
    int used, alloc, sign;
    mp_digit *dp;
} mp_int;

如您所见,它具有访问值的间接方式。 (mp_digit 是大整数的位数)。我想摆脱间接,所以在堆中有某种类似的结构,其中最后一个元素是 mp_digit[],其中每个 mp_int 实例的大小可能不同。

我可以使用 void* 和 malloc() 来做到这一点,因为我知道第一个 X 位置是带有信息(使用、分配、符号等)的 int,然后知道偏移量后访问 mp_digit[],但我不喜欢这样主意。我想知道哪种方法更好。

我发现了其他类似的问题,例如 this onethis one,但它们不会全部存储在堆中,所以我的问题有点棘手/不同。

谢谢,

【问题讨论】:

  • 请选择一种语言。
  • mp_digit *dp; 更改为 std::vector<mp_digit> dp; 删除 usedalloc
  • 作为定义和使用此类结构的示例,您可以查看LOGPALETTE (some usage example)。基本上,您只需分配缓冲区来保存结构本身,然后紧跟项目数组。
  • 您想要的整数不能用作局部变量。
  • @juanchopanza 我将使用 C++ 编译器对其进行编译,因此如果我们可以使用 C++ 的一些优点/抽象,那就太好了。如果我必须以 C 开发人员的身份编写应用程序的这一部分,我没有问题。

标签: c++ c heap-memory biginteger multiprecision


【解决方案1】:

C 中,mp_digit dp[] 表示灵活的数组成员。这出现在 C99 中:

typedef struct  {
    int used, alloc;
    signed char sign;
    mp_digit dp[];
} mp_int;

你可以用malloc(sizeof(mp_int) + alloc * sizeof(mp_digit));分配内存;也可以使用 realloc。

但是有一个模糊的东西可能会帮助您在这里节省一两个字节,具体取决于mp_digit 的类型——即dp 的偏移量不一定是sizeof(mp_int),但可能会更少;有一个用于计算要分配的 实际 最小大小的 kludgey 宏 hack(但这仍然是可移植的)。

该定义在 C++ 中不起作用,但您可以在 C++ 中使用指向不完整类型的指针。


请注意,灵活的数组成员不兼容here 等 1 字节数组

【讨论】:

    【解决方案2】:

    在 C 中创建类似这样的东西

    mp_int *LN_Create(int ndigits, int allocate)
    {
        mp_int *ln = calloc(1, sizeof mp_int);
    
        if (ln != NULL)
        {
            ln->ndigits = ndigits;
            if (allocate)
            {
                ln->dp = calloc(ndigits, sizeof mp_digit);
                ln->alloc = 1;
                if (ln->dp == NULL)
                {
                    free(ln);
                    ln = NULL;
                }
            }
        }
        return ln;
    }
    

    mp_int *LN_Create1(int ndigits)
    {
        size_t allocsize = sizeof mp_int + (ndigits - 1) * sizeof mp_digit;
        mp_int *ln = malloc(allocsize);
    
        if (ln != NULL)
        {
            memset(ln, 0, allocsize);
            ln->ndigits = ndigits;
        }
        return ln;
    }
    

    【讨论】:

    • 这完全没有意义,因为它需要 2 次分配并且没有删除间接性。
    • 这是 OP 所要求的。我不评论他的需求。结构中的字段准确地显示了他想要的内容。
    • 他写了“想要摆脱间接性”,你的代码显示的内容与他已经得到的基本相同。
    • 没注意到这句话
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-27
    相关资源
    最近更新 更多