2014-11-25 85 views
1

我有一个动态数组,其中包含方法push,pop并直接访问缓冲区。 直观地,我使该字段包含数组包含的元素数size_t。现在我添加如insertdeleteindexOf的方法。用于保存数据结构中元素数量的数据类型

然而,前两个期望的int作为位置时,使用负索引,用于选择从背面元件和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

:你最多可以有SIZE_MAX元素

禁忌:你只能以有限的方式

int

访问上述 INT_MAX部分

:接口是一致的与实施

禁忌:你不能以任何方式超过INT_MAX元素,也int为对象的大小unintuitively因为这是目的的size_t

回答

1

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

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

+0

我以'asprintf'为例,它返回一个字符串的长度(通常是'size_t'),因为错误时为'int'或'-1'。理论上,如果我在x86上使用'ptrdiff_t',那么在x86-16上size_t将是2字节,而'ptrdiff_t'是4字节,因此在x86上不必要地大,所以'PTRDIFF_MAX == INT_MAX' -64我还可以用'indexOf'等访问'INT_MAX'和'PTRDIFF_MAX'之间的部分,但'PTRDIFF_MAX'和'SIZE_MAX'之间的部分不会被覆盖。 – netcat 2014-11-25 15:28:05

+0

x86-16的更正:它实际上是唯一一个因大尺寸而工作的人,因为'ptrdiff_t'可以索引每个可能的元素,并且也指示错误或从后面选择,尽管它可能会更慢 – netcat 2014-11-25 15:37:14

+0

True ,不能保证'ptrdiff_t'的宽度足以防止指针减法溢出。事实上,为避免这种情况,有些实现会使'ptrdiff_t'比'size_t'更宽。然而,除非你处理一个非常大的数据集,否则这通常不是问题。 – downhillFromHere 2014-11-25 16:01:01

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) {...}