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

Automation of array allocation in C

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

Problem

I recently have been working on moving from projects written in Java and C++ to C and realized that the lack of std::vector in C makes it a bit more difficult to create multi-dimensional arrays. Also, without the std::string in C, it's harder to store arrays of strings and keep track of their sizes. To automate the process, I created a typedef'd struct: varray. varray attempts to emulate some basic functions of std::vector, e.g. storing sizes of the elements in an easily accessible location and allowing for allocation of multi-dimensional objects with "relative ease".

I've attached the header "varray.h" and a bit of sample code with comments to demonstrate its use. Please note that at this point, I haven't tried to dynamically expand the arrays, though I'll look into it as I practice more with the language.

If there is any feedback (syntax, memory allocation, anything), I'd greatly appreciate it - I'm still just getting started with C, C++, and Java.

varray.h

```
#ifndef VARRAY_H
#define VARRAY_H
#define VARRAY_DISPLAYDEBUG 0
#define VARRAY_STRSIZE(x) ((sizeof(char) * strlen(x)) + 1)
#include
#include
#include

typedef struct {
int* getInt;
char* getChar;
double* getDbl;
char* str;
int size;
} varray;

typedef enum {
v_char = 0,
v_int = 1,
v_double = 2,
v_varray = 3,
v_tdvarray = 4
} varrayType;

void* createArray(varrayType arrayType, int arraySize);
varray varrayPush(const char* data);
varray allocateNumArray(varrayType type, const int size);
varray allocateCharArray(const int size);
varray* allocateVarray(const int size);
varray** allocateTDVarray(const int size);

inline void* createArray(varrayType arrayType, int arraySize) {
varray* target;
varray** vtarget;
varray*** tdvtarget;
if (arrayType == v_char) {
target = malloc(sizeof(varray) * arraySize);
*target = allocateCharArray(arraySize);
return target;
}
else if (arrayType == v_int || arrayType == v_d

Solution

-
Too much memory

target = malloc(sizeof(varray) * arraySize);
      *target = allocateCharArray(arraySize);


allocates that many varray entries, and uses just one of them. If you insist on double indirection,

target = malloc(sizeof(varray));


is just enough. OTOH I don't see a need for a double indirection at all.

-
All pointers smell the same

There is no need to have pointers to all possible types. A single void * data would serve the same purpose. You should have getWhatever as accessor functions. You may want to associate the accessor function with the varray instance, eg:

typedef struct varray {
          void * (*get)(struct varray * v, size_t index);
          void * data;
          size_t size;
      }

      struct varray * allocateCharArray(size_t size)
      {
          ....
          v->get = vGetChar;
      }


where

void * vGetChar(varray * v, size_t index) {
          return (char *) v->data + index;
      }


-
Missing deallocations

Client has no resources to deallocate varrays.

-
Use standard library

To zero out allocated memory, use calloc. To copy a string, use strdup.

Code Snippets

target = malloc(sizeof(varray) * arraySize);
      *target = allocateCharArray(arraySize);
target = malloc(sizeof(varray));
typedef struct varray {
          void * (*get)(struct varray * v, size_t index);
          void * data;
          size_t size;
      }

      struct varray * allocateCharArray(size_t size)
      {
          ....
          v->get = vGetChar;
      }
void * vGetChar(varray * v, size_t index) {
          return (char *) v->data + index;
      }

Context

StackExchange Code Review Q#119449, answer score: 7

Revisions (0)

No revisions yet.