HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Generic Vector implementation

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
genericimplementationvector

Problem

I'm in the process of writing a Generic Container Library in C called CGCL. One of the generic containers I'm implementing is the vector container.

I'm writing this library to improve my knowledge of different data structures, improve my C coding skills, improve my skills with generic programming in C (as opposed to templates from C++), and also hopefully grow the library into something akin to the STL containers from C++ that all C developers can use when they need to use a common data structure (C doesn't have a standard data structure library).

I would like a review on the following (in this order of importance):

  • Correctness



  • Performance considerations (both memory and time improvements)



  • Code style



For some background information, the library naming convention for the container functions is something like:

gcl__


where the containers themselves are named like this: gcl_.

For reference, I'll be including some of the utility headers that contain some of the typedefs and enums I use in the code below. The actual code for the vector is in cgcl_vector.h/.c however.

cgcl_util.h

#ifndef CGCL_UTIL_H
#define CGCL_UTIL_H

#include 

typedef int (*GCLCompare)(const void *, const void *);

typedef bool(*GCLIsEqual)(const void *, const void *);

#endif


cgcl_errors.h

#ifndef CGCL_ERRORS_H
#define CGCL_ERRORS_H

typedef enum GCLError {
    eNoErr = 0,
    eInvalidArg,
    eFailedAlloc,
    eInvalidOperation,
    eOutOfBoundsAccess
} GCLError;

#endif


cgcl_vector.h

```
#ifndef CGCL_VECTOR_H
#define CGCL_VECTOR_H

#include "cgcl_errors.h"
#include "cgcl_util.h"
#include
#include

typedef struct gcl_vector___ gcl_vector;

gcl_vector *gcl_vector_init();

GCLError gcl_vector_push_back(gcl_vector v, void elem);
GCLError gcl_vector_insert(gcl_vector v, void elem, size_t pos);
GCLError gcl_vector_popback(gcl_vector *v);
GCLError gcl_vector_erase(gcl_vector *v, size_t pos);
GCLError gcl_vector_reserve(gcl_vector *v, size_t n);

void gc

Solution

-
Nullifying removed elements serve no purpose. You may safely drop memset(v->data, 0, v->size sizeof((v->data))); from clear, v->data[--v->size] = NULL; from popback, etc.

-
It is unclear why erase doesn't call memset but erases elements one by one.

On the same note, clear shall be expressed in terms of erase:

void gcl_vector_clear(gcl_vector *v)
{
    gcl_vector_erase(v, 0);
}


-
In foreach, the callback return value is ignored. I suppose declaring argument as void (callback)(void ) conveys this better.

-
I would consider to compile bound check feature conditionally.

-
shrink_to_fit is sorely missing.

Code Snippets

void gcl_vector_clear(gcl_vector *v)
{
    gcl_vector_erase(v, 0);
}

Context

StackExchange Code Review Q#123461, answer score: 2

Revisions (0)

No revisions yet.