2014-11-25 86 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) {...}