Thread: My own calloc() not working.

  1. #1
    Registered User
    Join Date
    Sep 2014
    Posts
    83

    My own calloc() not working.

    Hi,

    I'm trying to write my own version of the function calloc().
    Below is the code.
    Something goes wrong. The output when using my own calloc() is just random integers. The varibales in my_calloc don't seem to be local though, since the call a[0] in main gives the number assigned in my_calloc() (The code commented out).

    1) somebody knows what's wrong?
    2) if I correct it will my function my_calloc() work as the standard function calloc()?

    Code:
    // Trying out calloc()
    #include <stdio.h>
    #include <stdlib.h>
    
    int *my_calloc(size_t n, size_t size);
    
    int main(void)
    {
        int i, n;
        int *a;
        printf("Number of elements: ");
        scanf("%d", &n);
        
        //a = (int *) calloc(n, sizeof(int));
        a = my_calloc(n, sizeof(int));
        
        // Printfs just for test
        printf("a[0]: %d\n", a[0]);
        printf("a[1]: %d\n", a[1]);
        printf("a[2]: %d\n", a[2]);
        // End test
        
        printf("Enter numbers: \n");
        for(i = 0; i < n; i++)
            scanf("%d", &a[i]);
        printf("Numbers entered: \n");
        for(i = 0; i < n; i++)
            printf("%d  ", a[i]);
        printf("\n");
        
        
        return 0;
    
    }
    
    int *my_calloc(size_t n, size_t size)
    {
        int mem[n];
        int *ptr;
        ptr = mem;
        
        /* Just to test
        mem[0] = 3;
        mem[1] = 2;
        mem[2] = 1;
        printf("Inside my_calloc: %d\n", mem[0]);
        */
        return ptr;
    }

  2. #2
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    You cannot return a pointer to a non-static local variable. The storage reserved for that variable is freed upon return from the function, meaning the behavior of code like yours is undefined. It may crash, or it may appear to work correctly. It may even destroy your computer. Undefined behavior means the standard allows for any outcome. Your implementation of calloc is additionally incorrect in that it does not initialize the allocated memory to zero.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    mem is a local array, which means that it is destroyed when control returns from my_calloc.

    You could look into using lower level facilities, e.g., as provided by your operating system, in order to implement your own version of calloc. Or, you could create a large static array of char, then treat it as a pool of memory from which you allocate blocks as requested (and deallocate in my_free).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Sep 2014
    Posts
    83
    Thanks. Was trying to write:
    Code:
    static int mem[n];
    in my_calloc() but didnt work.
    Not sure what you mean with initializing memory to zero.

  5. #5
    Registered User
    Join Date
    Sep 2014
    Posts
    83
    Quote Originally Posted by laserlight View Post
    mem is a local array, which means that it is destroyed when control returns from my_calloc.

    You could look into using lower level facilities, e.g., as provided by your operating system, in order to implement your own version of calloc.
    OK, I think this will be a more complicated than I can handle now, maybe in the future

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    in my_calloc() but didnt work.
    That's possibly because your compiler doesn't support VLA with a static array. You should be dynamically allocating the memory.

    Jim

  7. #7
    Registered User
    Join Date
    Sep 2014
    Posts
    83
    Quote Originally Posted by laserlight View Post
    mem is a local array, which means that it is destroyed when control returns from my_calloc.
    But if mem is local, then why do the statements:
    Code:
        printf("a[0]: %d\n", a[0]);    printf("a[1]: %d\n", a[1]);
        printf("a[2]: %d\n", a[2]);
    in main print out what was assigned in my_calloc() (When comments removed)?

  8. #8
    Registered User
    Join Date
    Sep 2014
    Posts
    83
    Quote Originally Posted by jimblumberg View Post
    That's possibly because your compiler doesn't support VLA with a static array. You should be dynamically allocating the memory.

    Jim
    The compiler says: error: storage size of ‘mem’ isn’t constant
    static int mem[n];

    How do I allocate dynamically then (without calloc or using low low level facilities that Laserlight suggested)?

  9. #9
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    The compiler says: error: storage size of ‘mem’ isn’t constant
    That means that the size of the array must be a compile time constant.

    What exactly are you trying to accomplish?

    Why are you trying to write you're own calloc() function instead of just using the standard calloc()?

    Jim

  10. #10
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    I kind of assumed the my_calloc would be a function that uses malloc() and then initializes it to random values.

  11. #11
    Registered User
    Join Date
    Sep 2014
    Posts
    83
    Quote Originally Posted by jimblumberg View Post
    That means that the size of the array must be a compile time constant.

    What exactly are you trying to accomplish?

    Why are you trying to write you're own calloc() function instead of just using the standard calloc()?

    Jim
    I want to know how to write my own calloc() version to learn how it works. I'm new to programming and at the moment I'm learning about pointers and dynamically allocated memory.

  12. #12
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I suggest, since you're just learning, really learn the standard functions first. Then once you completely understand how to use the standard functions, malloc(), calloc(), realloc() and free(), it'll be much easier to understand how to roll your own.

    Jim

  13. #13
    Registered User
    Join Date
    Sep 2014
    Posts
    83
    OK, Thanks for the advice Jim, I think I will do that. Makes sense.

  14. #14
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by jjohan View Post
    But if mem is local, then why do the statements:
    Code:
        printf("a[0]: %d\n", a[0]);    printf("a[1]: %d\n", a[1]);
        printf("a[2]: %d\n", a[2]);
    in main print out what was assigned in my_calloc() (When comments removed)?
    There was a really good thread on this about a month ago. From what I understand, what you put in the memory may still be there. However it is not reserved space anymore, and can be overwritten by the creation of another variable, so it's not a reliable practice.
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

  15. #15
    Registered User
    Join Date
    Sep 2014
    Posts
    83
    Quote Originally Posted by Elkvis View Post
    You cannot return a pointer to a non-static local variable. The storage reserved for that variable is freed upon return from the function, meaning the behavior of code like yours is undefined. It may crash, or it may appear to work correctly. It may even destroy your computer. Undefined behavior means the standard allows for any outcome. Your implementation of calloc is additionally incorrect in that it does not initialize the allocated memory to zero.
    Then why does this work? Here a pointer to a local variable (new, in read_list) is returned too. Is the variable static?
    Code:
    struct tlist
    {
        char t;
        struct tlist *rest;
    };
    
    struct tlist *read_list(void)
    {
        struct tlist *new;
        char c;
        c = getchar();
        if(c != '\n')
        {
            new = create_list();
            new->t = c;
            new->rest = read_list();
            return new;
        }
        
        else 
            return NULL;    
    }
    
    struct tlist *create_list(void)
    {
        struct tlist *tp;
        tp = (struct tlist *) calloc(1, sizeof(struct tlist));
        if(tp == NULL)
        {
            fprintf(stderr, "No more memory.\n");
            exit(99);
        }
        else
            return tp;
    }
    Last edited by jjohan; 09-30-2014 at 04:54 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help with calloc
    By THERyu523 in forum C Programming
    Replies: 3
    Last Post: 03-14-2012, 08:57 PM
  2. calloc
    By dunsta in forum C Programming
    Replies: 5
    Last Post: 05-05-2010, 08:31 AM
  3. calloc
    By goran00 in forum C Programming
    Replies: 27
    Last Post: 04-07-2008, 12:50 PM
  4. Why use calloc()?
    By dwks in forum C Programming
    Replies: 8
    Last Post: 07-20-2005, 08:22 AM
  5. calloc()
    By goresus in forum C Programming
    Replies: 3
    Last Post: 01-20-2005, 09:50 AM