【问题标题】:Data type for holding the count of elements in a data structure用于保存数据结构中元素计数的数据类型
【发布时间】:2014-11-25 14:15:55
【问题描述】:

我有一个动态数组,其中包含 pushpop 方法并直接访问缓冲区。 直观地说,我使包含数组元素数量的字段包含size_t。现在我添加insertdeleteindexOf 等方法。

但是,前两个期望 intas 位置使用负索引从后面选择元素,indexOf 要么返回找到的位置,要么返回 -1 表示失败,导致:

struct array {
    size_t num;
    char *buf;
}

void array_push(char c) {...}
char array_pop() {...}
void array_insert(int pos, char c) {...}
void array_delete(int pos) {...}
int array_indexOf(char c) {...}

使用push/poparray.bufarray.num 的for 循环,我仍然可以访问最多SIZE_MAX 元素。 insertdelete 最多只能访问 INT_MAX 元素,而 indexOf 无法返回超过 INT_MAX 的位置。

您认为这个实现是正确的还是您会如何改变它?

size_t

pro:你最多可以有SIZE_MAX 个元素

反对:您只能以有限的方式访问INT_MAX 上方的部分

int

pro:接口将与实现保持一致

contra:你不能有超过INT_MAX元素,同样int对象的大小是不直观的,因为这是size_t的目的

【问题讨论】:

    标签: c arrays count int size-t


    【解决方案1】:

    不要限制实施。将带有 size_t 参数的方法添加到接口。

    void array_insert_beg(size_t pos, char c) {...}
    void array_insert_end(size_t pos, char c) {...}
    ...
    bool array_find(char c, size_t *index) {...}
    

    【讨论】:

      【解决方案2】:

      在我看来,在您的情况下,保留size_t 并使用ptrdiff_t 而不是int 作为函数参数和返回值更自然。您可以在stddef.h 中找到它,顾名思义,它旨在用于数组索引和地址算术。

      请注意,虽然ptrdiff_t 是两个指针相减的结果,但不能保证这样做时不会溢出。因此,当您处理非常大的对象时,它可能会导致问题,在这种情况下,使用指定宽度的整数类型可能会更好,例如,int_fast64_t

      【讨论】:

      • 我以asprintf 为例,它返回字符串的长度(通常也是size_t)作为int-1 出错。理论上,如果我在 x86 上使用 ptrdiff_t 不会有任何区别 PTRDIFF_MAX == INT_MAX,在 x86-16 上 size_t 将是 2 个字节,但 ptrdiff_t 是 4 个字节,因此不必要地大,在 x86-64 上我还可以使用indexOf 等访问INT_MAXPTRDIFF_MAX 之间的部分,但PTRDIFF_MAXSIZE_MAX 之间的部分还不会被覆盖。
      • x86-16 的更正:由于更大的尺寸,它实际上是唯一有效的,因为ptrdiff_t 可以索引每个可能的元素,也可以指示错误或从后面选择,尽管它可能会更慢
      • 没错,不能保证ptrdiff_t 的宽度足以防止指针减法溢出。事实上,一些实现使ptrdiff_tsize_t 更宽以避免这种情况。但是,除非您处理的是非常大的数据集,否则这通常不是问题。
      猜你喜欢
      • 1970-01-01
      • 2012-01-07
      • 2019-08-28
      • 2012-08-27
      • 1970-01-01
      • 2016-03-23
      • 1970-01-01
      • 1970-01-01
      • 2021-05-08
      相关资源
      最近更新 更多