patterncMinor
Generic dynamic array
Viewed 0 times
arraygenericdynamic
Problem
Here is the interface of my generic dynamic array;
and this is the implementation of my generic dynamic array:
```
/ dynamic array implementation /
#include / memcpy /
#include / free /
#include "xalloc.h" / xmalloc, xrealloc /
struct dynamic_array {
size_t cap;
size_t len;
size_t unitsize;
char data[1];
};
#define DATAOFFSET ((unsigned long)(((struct dynamic_array*)0)->data))
#define DA_STRUCT(DATAPTR) (struct dynamic_array )((char )DATAPTR-DATAOFFSET)
void *danew(size_t unitsize)
{
/ -1 because we already have one byte in struct /
struct dynamic_array *da = xmalloc(sizeof(struct dynamic_array) +
unitsize - 1);
da->cap = 1;
da->len = 0;
da->unitsize = unitsize;
return &(da->data);
}
static __inline struct dynamic_array __dagrow(struct dynamic_array da,
size_t size)
{
while(size > da->cap)
da->cap = 2*da->cap;
/ -1 because we already have one byte in sizeof(struct) /
return xrealloc(da, sizeof(struct dynamic_array) + da->unitsize*da->cap
- 1);
}
void daappend(void arr, const void *elem)
{
struct dynamic_array *da = DA_STRUCT(arr);
da = __dagrow(da, da->len + 1);
memc
/* dynamic array interface */
#ifndef DA_HEADER
#define DA_HEADER
#include /* size_t */
/* creates a new dynamic array, with each element of "size" bytes */
void *danew(size_t unitsize);
/* returns pointer to element after the last element */
void *daend(void *arr);
/* appends new element after last element
return pointer to array head
*/
void *daappend(void *arr, const void *elem);
/*
removes the last element and returns a pointer to it or null if empty
*/
void *dapop(void *arr);
/*
frees the array
*/
void dafree(void *arr);
#endif /* DA_HEADER */and this is the implementation of my generic dynamic array:
```
/ dynamic array implementation /
#include / memcpy /
#include / free /
#include "xalloc.h" / xmalloc, xrealloc /
struct dynamic_array {
size_t cap;
size_t len;
size_t unitsize;
char data[1];
};
#define DATAOFFSET ((unsigned long)(((struct dynamic_array*)0)->data))
#define DA_STRUCT(DATAPTR) (struct dynamic_array )((char )DATAPTR-DATAOFFSET)
void *danew(size_t unitsize)
{
/ -1 because we already have one byte in struct /
struct dynamic_array *da = xmalloc(sizeof(struct dynamic_array) +
unitsize - 1);
da->cap = 1;
da->len = 0;
da->unitsize = unitsize;
return &(da->data);
}
static __inline struct dynamic_array __dagrow(struct dynamic_array da,
size_t size)
{
while(size > da->cap)
da->cap = 2*da->cap;
/ -1 because we already have one byte in sizeof(struct) /
return xrealloc(da, sizeof(struct dynamic_array) + da->unitsize*da->cap
- 1);
}
void daappend(void arr, const void *elem)
{
struct dynamic_array *da = DA_STRUCT(arr);
da = __dagrow(da, da->len + 1);
memc
Solution
-
naming
-
returning
naming
da* + all lower case makes it hard to parse the difference between the prefix and the name of the function, instead either pick da_snake_case or daCamelCase.-
returning
void* is not ideal instead create a opaque (incomplete) struct and just let the use pass pointers to that struct around:struct DynamicArray;
DynamicArray* danew(size_t unitsize);Code Snippets
struct DynamicArray;
DynamicArray* danew(size_t unitsize);Context
StackExchange Code Review Q#85495, answer score: 3
Revisions (0)
No revisions yet.