Data type for holding the count of elements in a data structure

142 views Asked by At

I have a dynamic array with the methods push, pop and direct acces to the buffer. Intuitively I make the field containing the number of elements the array contains a size_t. Now I add methods like insert, delete and indexOf.

However, the first two expect an intas position to use negative indices for selecting elements from the back and indexOf either returns the found position or -1 to indicate failure, resulting in:

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

With push/pop and a for-loop over array.buf with array.num I could still access up to SIZE_MAX elements. insert and delete can access only up to INT_MAX elements, though, and indexOf couldn't return positions over INT_MAX.

Would you consider this implementation correct or how would you change it?

size_t

pro: you can have up to SIZE_MAX elements

contra: you could access the portion above INT_MAX only in a limited way

int

pro: the interface would be coherent with the implementation

contra: you can't have more than INT_MAX elements in any way, also int for the size of an object is unintuitively as that's the purpose of size_t

2

There are 2 answers

0
potrzebie On

Don't restrict the implementation. Add methods with size_t arguments to the interface.

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

It seems to me that, in your case, it's more natural keep size_t and use ptrdiff_t instead of int for the function arguments and return values. You can find it in stddef.h and as the name suggests, it's intended to be used for array indexing and address arithmetic.

Be aware that although ptrdiff_t is the result of substracting two pointers, there's no guarantee that it doesn't overflow when doing so. So it can cause problems when you're dealing with very large objects, in which case it's probably better to use specified-width integer types, e.g., int_fast64_t.