Hi,

I created a structure Vector and implement some functions to make the new defined type (vector) dynamically allocated and resized (inspired from the C++ implementation of the dynamic arrays : vector). I need to assign a structure to every vector element but I am not sure that I am doing it right:

here is the structure that I ve defined:

************************************************** **********

typedef struct 
{
void** mem; // to make this parametrizable I want the void* to point to a Structure (referenced with * a pointer)
unsigned long elems;
unsigned long elemsize; //element size
unsigned long capelems; //capacity of the vector.Returns the size of the storage space
//currently allocated for the vector, expressed in terms of elements
unsigned long reserve; 
} Vector;

************************************************** **********

the source file is given below:
************************************************** **********

//action of setting a new vector
Vector* newVector(void *data, unsigned long elemsize)
{
Vector* pvec = (Vector*)malloc(sizeof(Vector)); //memory space set
if( pvec == NULL )
FatalError("Malloc failed.\n");
memset(pvec, 0, sizeof(Vector));

pvec->reserve = 1024;
pvec->capelems = pvec->reserve;
pvec->elemsize = elemsize;
pvec->elems = 0;

pvec->mem = (data)malloc(pvec->capelems * pvec->elemsize); //pvec->elemsize is the sizeof(data)
if( pvec->mem == NULL )
FatalError("Vector Malloc failed.\n");
memset(pvec->mem, 0, sizeof(pvec->capelems * pvec->elemsize));
return pvec;
}

//action of deleting a vector
void deleteVector(Vector* pvec)
{
free(pvec->mem);
free(pvec);
}

//action of extending a vector size
void resizeVector((Vector* pvec, void* data, unsigned long capacity)
{
pvec->capelems = capacity;
void* mem = (data)malloc((pvec->capelems + pvec->reserve) * pvec->elemsize);
memcpy(mem, pvec->mem, pvec->elems * pvec->elemsize); //copy characters from memory
free(pvec->mem);
pvec->mem = mem;
pvec->capelems += pvec->reserve;
}

//action of pushing back an element to a vector
//Adds a new element at the end of the vector, after its current
//last element.The content of val is copied (or moved) to the new element
void push_backVector(Vector* pvec, void* data, unsigned long elemsize)
{
assert(elemsize == pvec->elemsize); //check certain conditions at run time
if (pvec->elems == pvec->capelems) 
{
resizeVector(pvec, pvec->capelems);
}
memcpy(pvec->mem + (pvec->elems * pvec->elemsize), data, pvec->elemsize); 
pvec->elems++; 
}

//action of returning the vector length
unsigned long lengthVector(Vector* pvec)
{
return pvec->elems;
}

//action of returning a value of index "index" of a vector "vector"
void* getVectorElement(Vector* pvec, unsigned long i_index)
{
assert(i_index < pvec->elems); //if evaluated to False, an error message is returned and program aborted
return (void*)(pvec->mem + (i_index * pvec->elemsize)); 
}

//action of copying an item of a vector
void copyVectorItem(Vector* pvec, void* destination, unsigned long i_index)
{
memcpy(destination, getVectorElement(pvec, i_index), pvec->elemsize);
}

************************************************** **********

I believe I have serious problems with pointers, values and dereferencing a pointer.

Can anyone give me a hand please.

Regards

N.Wilson

I have a structure called Switch that I would like to use in my vector NetRouters of type Vector. Is this the right way to call the newVector function for instance ?

  NetRouters = newVector(Switch *aSwitch, (unsigned long) sizeof(Switch*)); 

You have several syntax errors. Here are the corrections. Note that the return value of malloc() can't be typecase to something called data. In C language a typecase of void* return value is necessary (but it is in c++).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include  "Vector.h"

void FatalError(const char* msg)
{
    puts(msg);
    exit(1);
}

//action of setting a new vector
Vector* newVector(void *data, unsigned long elemsize)
{
    Vector* pvec = (Vector*) malloc(sizeof(Vector)); //memory space set
    if (pvec == NULL)
        FatalError("Malloc failed.\n");
    memset(pvec, 0, sizeof(Vector));

    pvec->reserve = 1024;
    pvec->capelems = pvec->reserve;
    pvec->elemsize = elemsize;
    pvec->elems = 0;

    pvec->mem = malloc(pvec->capelems * pvec->elemsize); //pvec->elemsize is the sizeof(data)
    if (pvec->mem == NULL)
        FatalError("Vector Malloc failed.\n");
    memset(pvec->mem, 0, sizeof(pvec->capelems * pvec->elemsize));
    return pvec;
}

//action of deleting a vector
void deleteVector(Vector* pvec)
{
    free(pvec->mem);
    free(pvec);
}

//action of extending a vector size
void resizeVector(Vector* pvec, void* data, unsigned long capacity)
{
    pvec->capelems = capacity;
    void* mem = malloc((pvec->capelems + pvec->reserve) * pvec->elemsize);
    memcpy(mem, pvec->mem, pvec->elems * pvec->elemsize); //copy characters from memory
    free(pvec->mem);
    pvec->mem = mem;
    pvec->capelems += pvec->reserve;
}

//action of pushing back an element to a vector
//Adds a new element at the end of the vector, after its current
//last element.The content of val is copied (or moved) to the new element
void push_backVector(Vector* pvec, void* data, unsigned long elemsize)
{
    assert(elemsize == pvec->elemsize); //check certain conditions at run time
    if (pvec->elems == pvec->capelems)
    {
        resizeVector(pvec, data, pvec->capelems);
    }
    memcpy(pvec->mem + (pvec->elems * pvec->elemsize), data, pvec->elemsize);
    pvec->elems++;
}

//action of returning the vector length
unsigned long lengthVector(Vector* pvec)
{
    return pvec->elems;
}

//action of returning a value of index "index" of a vector "vector"
void* getVectorElement(Vector* pvec, unsigned long i_index)
{
    assert(i_index < pvec->elems); //if evaluated to False, an error message is returned and program aborted
    return (void*) (pvec->mem + (i_index * pvec->elemsize));
}

//action of copying an item of a vector
void copyVectorItem(Vector* pvec, void* destination, unsigned long i_index)
{
    memcpy(destination, getVectorElement(pvec, i_index), pvec->elemsize);


}

Edited 2 Years Ago by Ancient Dragon

Is this the right way to call the newVector function for instance ?

No.

#include "Vector.h"


typedef struct tagSwitch
{
    int a, b;
} Switch;

int main(int argc, char* argv[])
{
    Switch* aSwitch = 0;
    Vector* NetRouters = newVector(aSwitch, sizeof(Switch*));
    return 0;
}

Many thanks Ancient Dragon,

can I cast the return type of malloc (void *) to another type ( Struct Switch *) in this case?
It is what I try to do by writing

Vector* NetRouters = newVector(aSwitch, sizeof(Switch*));

Is to have a vector of elements where every case is of type (Switch *)

Regards
N.Wilson

I thought of changing the function newVector.
is it right to do the following ?

Vector* newVector(void *data, unsigned long elemsize)
{
    Vector* pvec = (Vector*)malloc(sizeof(Vector)); //memory space set
    if( pvec == NULL )
     FatalError("Malloc failed.\n");
     memset(pvec, 0, sizeof(Vector));

    pvec->reserve = 1024;
    pvec->capelems = pvec->reserve;

    elemsize = sizeof (data);
    pvec->elemsize = elemsize;

    pvec->elems = 0;

    data = malloc(pvec->capelems * pvec->elemsize); //pvec->elemsize is the sizeof(data);
    if(  data == NULL )
       FatalError("Vector Malloc failed.\n");
       memset(data, 0, sizeof(pvec->capelems * pvec->elemsize));

    pvec->mem = data;

    return pvec;
}

can I cast the return type of malloc (void *) to another type ( Struct Switch *)

You can cast the return value of malloc() to anything you want, but that doesn't make any sense to allocate memory for sizeof(struct Switch) then assign it to Vector*.

I thought of changing the function newVector.

Looks like that will work. Just make sure that data does not get desroyed outside of the Vector class. For example

int* data = malloc(sizeof(int)*10);
Vector* = newVector(data,1000);
free(data); // this will invalidate the pointer stored in Vector

Edited 2 Years Ago by Ancient Dragon

This article has been dead for over six months. Start a new discussion instead.