Generalise functions by specifying type as an argument

This is a discussion on Generalise functions by specifying type as an argument within the C Programming forums, part of the General Programming Boards category; Hi there This is not an urgent question, I'm just curious to know if there is an answer. I've done ...

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    6

    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?

    Thanks in advance
    Gib

  2. #2
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,627
    >>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);
    }
    Last edited by Elysia; 07-05-2010 at 06:06 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    It fails because you're assuming sizeof(int) == sizeof(int *) and sizeof(float) == sizeof(float *).

  4. #4
    Registered User
    Join Date
    Apr 2010
    Posts
    6
    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. #5
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    I'd like to know the answer to the question, is there a form of templates for C?

  6. #6
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    An interesting attempt: flipcode - Faking Templates In C

  7. #7
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Quote Originally Posted by User Name: View Post
    An interesting attempt: flipcode - Faking Templates In C
    Which has far more problems than it solves...

  8. #8
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    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...
    Last edited by claudiu; 07-06-2010 at 02:19 AM.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  9. #9
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,627
    Quote Originally Posted by User Name: View Post
    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.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    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?
    Last edited by Bayint Naung; 07-06-2010 at 08:05 AM. Reason: forgot to de-allocate memory

  11. #11
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,627
    This is not fine. You're leaking memory.
    And what exactly does "side effect" mean in this context?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Oh please just an example. Elysia

  13. #13
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,627
    Examples are no reason not to free... especially since you posted not snippets, but the entire function/code.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Examples are no reason not to free... especially since you posted not snippets, but the entire function/code.
    You are right. Satizfied?

  15. #15
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,627

    You couldn't actually include the free code, could you?
    Oh well. At least they know it must be freed.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. passing argument from incompatible pointer type
    By bhdavis1978 in forum C Programming
    Replies: 5
    Last Post: 03-17-2010, 12:42 PM
  2. Replies: 3
    Last Post: 12-11-2009, 09:44 PM
  3. Conversion of pointers to functions
    By hzmonte in forum C Programming
    Replies: 0
    Last Post: 01-20-2009, 12:56 AM
  4. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  5. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21