Difference in uses between malloc and calloc

前端 未结 7 439
花落未央
花落未央 2020-12-22 05:00
gcc 4.5.1 c89

I have written this source code for my better understanding of malloc and calloc.

I understand, but just have a few questions

相关标签:
7条回答
  • 2020-12-22 05:23

    malloc(n) allocates n bytes plus padding and overhead.

    calloc(m, n) allocates m*n bytes plus padding and overhead, and then zero's the memory.

    That's it.

    0 讨论(0)
  • 2020-12-22 05:23

    All three loops in your program use only one struct Devices object at a time. The later ones allocate extra memory as though they are going to use multiple objects, but then keep overwriting the beginning of that memory. If you tried to use the object with ID 1 after setting up the object with ID 2, you would find there is no longer any object with ID 1.

    Instead, you could do something like this to treat the allocated memory as an array of structs:

    dev_malloc = malloc(num_devices * sizeof *dev_malloc);
    for (i=0; i<num_devices; i++) {
        /* Assign values */   
        dev_malloc[i].id = i + 1;   
        sprintf(dev_malloc[i].name, "dev_malloc%zu", dev_malloc[i].id);   
        /* Print values */   
        printf("ID ----- [ %zu ]\n", dev_malloc[i].id);   
        printf("Name --- [ %s ]\n", dev_malloc[i].name);
    }
    free(dev_malloc);
    
    0 讨论(0)
  • 2020-12-22 05:30

    edited for clarity

    • I guess the first one and the second is creating a pointer to 5 struct device. And the third is creating a single pointer to a struct device?

    The first one malloc(number * sizeof(*devices)) would allocate enough memory to store number of Devices. As others have mentioned, you can treat this block like an array of Device. The pointer you get back will point to the beginning of the block.

    int number = 5;
    Device *ptr = malloc(number * sizeof(*ptr));
    /* stuff */
    free(ptr);
    

    The second one that uses calloc does the same thing, while also initializing the memory to 0. Again, you can use treat the block like an array of Device.

    int number = 5;
    Device *ptr = calloc(number, sizeof(*ptr));
    /* stuff */
    free(ptr);
    

    The third one, looping 5 times, would result in 5 different pointers to 5 different blocks large enough to store one Device each. This also means each of the 5 pointers has to be free'ed individually.

    Device *ptrs[5];
    for(int i = 0; i < 5; ++i)
    {
        ptrs[i] = malloc(sizeof(*ptrs[i]));
    }
    /* stuff */
    for(int i = 0; i < 5; ++i)
    {
        free(ptrs[i]);
    }
    
    0 讨论(0)
  • 2020-12-22 05:30

    Look at an implementation of calloc to see the differences. It's probably something like this:

    // SIZE_MAX is defined in stdint.h from C99
    void *calloc( size_t N, size_t S)
    {
        void *ret;
        size_t NBYTES;
    
        // check for overflow of size_t type
        if (N > SIZE_MAX / S) return NULL;
    
        NBYTES = N * S;
        ret = malloc( NBYTES);
        if (ret != NULL)
        {
            memset( ret, 0, NBYTES);
        }
    
        return ret;
    }
    
    0 讨论(0)
  • 2020-12-22 05:33

    calloc(a,b) and malloc(a*b) are equivalent except for the possibility of arithmetic overflow or type issues, and the fact that calloc ensures the memory is zero-byte-filled. Either allocated memory that can be used for an array of a elements each of size b (or vice versa). On the other hand, calling malloc(b) a times will results in a individual objects of size b which can be freed independently and which are not in an array (though you could store their addresses in an array of pointers).

    Hope this helps.

    0 讨论(0)
  • 2020-12-22 05:33

    As you point out, calloc zeroes out the memory is allocates, while malloc doesn't.

    Your examples 1 & 2 each allocate a single contiguous block of five structs (and returns a pointer to that block), whereas example 3 allocates five separate blocks of one struct each (and gives you five pointers unrelated to one another.)

    0 讨论(0)
提交回复
热议问题