# Thread: Generalise functions by specifying type as an argument

1. ## Generalise functions by specifying type as an argument

Hi there

This is not an urgent question, I'm just curious to know if there is an answer. I've done a search but nothing has come up - I suspect this is because I don't know how to pose the question succinctly.

I use this function to dynamically allocate 2D arrays of type int:

Code:
```int **get_space_i(int m, int n)
{
int i, *p, **a;
p = malloc(m * n * sizeof(int));
a = malloc(m * sizeof(int *));
for(i = 0; i < m; i++) a[i] = p + (i * n);
return a;
}```
and this one to do the same for floats:

Code:
```float **get_space_f(int m, int n)
{
int i;
float *p, **a;
p = malloc(m * n * sizeof(float));
a = malloc(m * sizeof(float *));
for(i = 0; i < m; i++) a[i] = p + (i * n);
return a;
}```
and the same for doubles, structs etc. This is how it's used:

Code:
```int *X, rows, cols;
X = get_space_i(rows,cols);```
So I was wondering if there was a way that I could make one generic function where a third argument specifies the type? I tried something like this:

Code:
```void **get_space(int m, int n, size_t size)
{
int i;
void *p, **a;
p = malloc(m * n * size);
a = malloc(m * size);
for(i = 0; i < m; i++)
{
a[i] = p + (i*n);
}
return a;
}

int **a;
float **b;
a = (int **)get_space(m,n,sizeof(int));
b = (float **)get_space(m,n,sizeof(float));```
but it segfaults. Any ideas how this might work?

Gib

2. >>a = malloc(m * size);
I believe this is wrong. You need to allocate space for pointers.
So pass an extra argument for the size of a pointer of the type you're allocating.

And just for the sake of it, because I'm feeling rebellious, a C++ solution:
Code:
```#include <vector>

template<typename T>
std::vector< std::vector<T> > Build2DVector(int m, int n)
{
return std::vector< std::vector<T> >(m, std::vector<T>(n));
}

int main()
{
auto && a = Build2DVector<int>(10, 10);
auto && b = Build2DVector<float>(10, 10);
}```

3. It fails because you're assuming sizeof(int) == sizeof(int *) and sizeof(float) == sizeof(float *).

4. Cool it works, many thanks! Stupid mistake I guess. Just for completeness here is the working version:
Code:
```void **get_space(int m, int n, size_t size, size_t psize)
{
int i;
void *p, **a;
p = malloc(m * n * size);
a = malloc(m * psize);
for(i = 0; i < m; i++)
{
a[i] = p + (i*n);
}
return a;
}

int **a, m, n;
float **b;

a = (int **)get_space(m,n,sizeof(int),sizeof(int*));
b = (float **)get_space(m,n,sizeof(float),sizeof(float*));```

5. I'd like to know the answer to the question, is there a form of templates for C?

6. An interesting attempt: flipcode - Faking Templates In C

7. Originally Posted by User Name:
An interesting attempt: flipcode - Faking Templates In C
Which has far more problems than it solves...

8. Adding templates to C is like putting a saddle on a motorcycle because you are used to riding on a horse.

EDIT: Well perhaps this is not the best example since motorcycles also have a saddle albeit a very different one. But you know what I mean...

9. Originally Posted by User Name:
I'd like to know the answer to the question, is there a form of templates for C?
No. You can certainly try faking them, but there is no real core functionality.
And there probably never will be, just as there probably never will be references, and other C++ things.
You'll have to ask the standards committee about the why, however.

10. Code:
```#define NEW_VECTOR(vec,m,n)        (vec = get_space(m,n,sizeof(*vec),sizeof(vec) ))
void *get_space(int m, int n, size_t psize,size_t size)
{
int i;
void *p, **a;
p = malloc(m * n * size);
a = malloc(m * psize);
for(i = 0; i < m; i++)
{
a[i] = (char*) p + (i*n * size);
}
return a;
}

void delete_vector(void *a)
{
void **array = a;
free( *array );
free( array );
}

int main(void)
{
int **ia;
double **da;

NEW_VECTOR(ia,3,5);
NEW_VECTOR(da,5,7);

delete_vector(ia);
delete_vector(da);
/* code to free ia and da accordingly
requested by Elysia
*/
return 0;
}```
It's fine even if you have side effect like:
int **a[10];
int i = 0;
NEW_VECTOR(a[i++], 3, 3 );
Why?

11. This is not fine. You're leaking memory.
And what exactly does "side effect" mean in this context?

12. Oh please just an example. Elysia

13. Examples are no reason not to free... especially since you posted not snippets, but the entire function/code.

14. Examples are no reason not to free... especially since you posted not snippets, but the entire function/code.
You are right. Satizfied?

15. You couldn't actually include the free code, could you?
Oh well. At least they know it must be freed.

Popular pages Recent additions