E
Edd
Hello all,
I've made a data structure and an associated set of functions to enable me
to store a dynamically-sized array of elements of whatever data type I like.
Well that's the idea anyway...
My implementation seems to work great for primitive types, structures and
unions, but I can't quite get an array of function-pointers working
properly. Here's a very reduced version of my code with error checks removed
for the sake of brevity.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define ALLOC_FACTOR 10
/* Dynamically-allocated array structure */
typedef struct TYPE_ARRAY {
void *base;
size_t elsz;
unsigned block, len;
}
ARRAY;
/* Initialise an array to an 'empty' state */
int InitArray(ARRAY *a, size_t elsz){
a->base = NULL;
a->elsz = elsz;
a->block = a->len = 0;
return 0;
}
/* Add an element to an array */
int AddElement(ARRAY *a, void *el){
/* Allocate some space if necessary */
if(a->block == a->len){
a->base = realloc(a->base, a->elsz*(a->block + ALLOC_FACTOR));
a->block += ALLOC_FACTOR;
}
/* Copy a new element on to the end of the array */
memmove((char *)(a->base) + (a->elsz*a->len++), el, a->elsz);
return 0;
}
/* Get the address of the kth element */
void *GetElement(ARRAY *a, unsigned k){
return (char *)(a->base) + (k * a->elsz);
}
int main(void){
double (*f)(double);
ARRAY funcs;
InitArray(&funcs, sizeof(sin));
/* Add some functions to the funcs ARRAY */
AddElement(&funcs, &sin);
AddElement(&funcs, &tan);
AddElement(&funcs, &exp);
AddElement(&funcs, &log);
/* Get the ARRAY element at index 2 */
f = *(double (**)(double))GetElement(&funcs, 2);
/* This should now display "f(1.0) = 2.718..."? */
printf("f(%lf) = %lf\n", 1.0, f(1.0));
return 0;
}
This program crashes when I run it. Am I doing something undefined here? I
can't see what's going wrong. I think it may be my understanding of
function-pointer syntax is a little lacking, but what I've got still seems
fine to me.
Here's an alternative main() function which makes a dynamic array of doubles
instead of function pointers. This one seems to work fine:
int main(void){
double src[4] = {0.0, 1.0, 3.14, 2.718};
ARRAY dbls;
InitArray(&dbls, sizeof(double));
double d;
/* Add some doubles to the dbls ARRAY */
AddElement(&dbls, src);
AddElement(&dbls, src+1);
AddElement(&dbls, src+2);
AddElement(&dbls, src+3);
/* Get the ARRAY element at index 2 */
d = *(double *)GetElement(&dbls, 2);
/* This should now display "d = 3.14" */
printf("d = %lf\n", d);
return 0;
}
Can anyone point me in the right direction?
Thanks in advance,
Edd
I've made a data structure and an associated set of functions to enable me
to store a dynamically-sized array of elements of whatever data type I like.
Well that's the idea anyway...
My implementation seems to work great for primitive types, structures and
unions, but I can't quite get an array of function-pointers working
properly. Here's a very reduced version of my code with error checks removed
for the sake of brevity.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define ALLOC_FACTOR 10
/* Dynamically-allocated array structure */
typedef struct TYPE_ARRAY {
void *base;
size_t elsz;
unsigned block, len;
}
ARRAY;
/* Initialise an array to an 'empty' state */
int InitArray(ARRAY *a, size_t elsz){
a->base = NULL;
a->elsz = elsz;
a->block = a->len = 0;
return 0;
}
/* Add an element to an array */
int AddElement(ARRAY *a, void *el){
/* Allocate some space if necessary */
if(a->block == a->len){
a->base = realloc(a->base, a->elsz*(a->block + ALLOC_FACTOR));
a->block += ALLOC_FACTOR;
}
/* Copy a new element on to the end of the array */
memmove((char *)(a->base) + (a->elsz*a->len++), el, a->elsz);
return 0;
}
/* Get the address of the kth element */
void *GetElement(ARRAY *a, unsigned k){
return (char *)(a->base) + (k * a->elsz);
}
int main(void){
double (*f)(double);
ARRAY funcs;
InitArray(&funcs, sizeof(sin));
/* Add some functions to the funcs ARRAY */
AddElement(&funcs, &sin);
AddElement(&funcs, &tan);
AddElement(&funcs, &exp);
AddElement(&funcs, &log);
/* Get the ARRAY element at index 2 */
f = *(double (**)(double))GetElement(&funcs, 2);
/* This should now display "f(1.0) = 2.718..."? */
printf("f(%lf) = %lf\n", 1.0, f(1.0));
return 0;
}
This program crashes when I run it. Am I doing something undefined here? I
can't see what's going wrong. I think it may be my understanding of
function-pointer syntax is a little lacking, but what I've got still seems
fine to me.
Here's an alternative main() function which makes a dynamic array of doubles
instead of function pointers. This one seems to work fine:
int main(void){
double src[4] = {0.0, 1.0, 3.14, 2.718};
ARRAY dbls;
InitArray(&dbls, sizeof(double));
double d;
/* Add some doubles to the dbls ARRAY */
AddElement(&dbls, src);
AddElement(&dbls, src+1);
AddElement(&dbls, src+2);
AddElement(&dbls, src+3);
/* Get the ARRAY element at index 2 */
d = *(double *)GetElement(&dbls, 2);
/* This should now display "d = 3.14" */
printf("d = %lf\n", d);
return 0;
}
Can anyone point me in the right direction?
Thanks in advance,
Edd