简体   繁体   中英

Malloc calloc fails to allocate structure

I get null memory using following code of malloc/calloc. Sometimes it fails to allocate memory for "name1" and then strcpy fails. Please guide.

struct testMalloc
{
    char name1[90];
    char name2[90]; 
    struct testMalloc* ptr;
};
int main(int argc, char* argv[])
{
    struct testMalloc* test = 0 ;   
    int size = 0;
    size = sizeof(struct testMalloc);

    printf("Size of struct is %d", size);

    test = (struct testMalloc*) calloc(sizeof(struct testMalloc));  
    
    strcpy((test->name1), "hdshdssdsdfsfffffffffffffffffffffffffffffh");

    return 0;

}

You do not include <stdlib.h> for the compiler to know the signature of calloc and in this case it uses K&R calling convention.

If you include <stdlib.h> the code won't compile before to correctly call the calloc .

calloc takes 2 arguments: the number of elements, and the size of each element. It will zero out the allocated memory. What you're looking for is malloc , which only takes 1 argument: the total size of the allocated memory chunk, and it does not zero out the allocated memory.

  1. Always check the result of malloc.
  2. Use the objects instead of types in sizeof
  3. Try to use safer versions of string functions (in this example passed string is longer that the array.
  4. You do not have to cast result of the malloc and it is considered as bad practice (nowadays rather obsolete but anyway)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct testMalloc
{
    char name1[20];
    char name2[90]; 
    struct testMalloc* ptr;
};

struct testMalloc *allocAndCopy(const char *str)
{
    struct testMalloc *ptr = malloc(sizeof(*ptr));
    if(ptr)
    {
        strncpy(ptr -> name1, str, sizeof(ptr -> name1));
        ptr -> name1[sizeof(ptr -> name1) - 1] = 0;
    }
    return ptr;
}


int main(int argc, char* argv[])
{
    struct testMalloc* test = allocAndCopy("hdshdssdsdfsfffffffffffffffffffffffffffffh");

    if(test) printf("the string is: %s\n", test -> name1);
}

https://godbolt.org/z/zjvvYW

There are few syntax errors:

  1. struct testMalloc* test = NULL; This is how a NULL pointer is initialized
  2. calloc(sizeof(struct testMalloc)); too few arguments passed to calloc . The correct form is calloc(no_of_elements, sizeof(type));

Here is the correct implementation of your code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct testMalloc
{
    char name1[90];
    char name2[90]; 
    struct testMalloc* ptr;
};

int main(int argc, char* argv[])
{
    struct testMalloc* test = NULL;
    size_t size = sizeof(struct testMalloc);

    printf("Size of struct is %ld\n", size);

    if((test = (struct testMalloc*)calloc(1, size)) == NULL){
        return -1; //Failed to allocate memory
    }
    else {
        strcpy((test->name1),"hdshdssdsdfsfffffffffffffffffffffffffffffh");
        printf("%s\n",test->name1);
    }
    
    return 0;
}

From top to bottom:

1.

You forgot to #include stdlib.h to use calloc() and malloc() . Implicit declarations are prohibited since C99.

2.

int main(int argc, char* argv[])

Your program does not need to get arguments into it.

This:

int main (void)

would be more appropriate.

3.

int size = 0;

size should never have a negative value. So it would be more appropriate to declare it as unsigned int or even better size_t .

4.

struct testMalloc* test = 0 ; 

You can use 0 to initialize a pointer. It's perfectlty valid as 0 is a null pointer constant . But better use NULL when dealing with pointers and not 0 to show the pointer intention and increase the readability.

struct testMalloc* test = NULL; 

5.

calloc(sizeof(struct testMalloc)); 

calloc requires two arguments in comparison to malloc . The first needs to be number of items and the second the size of one item.

calloc(sizeof(1,struct testMalloc)); 

6.

test = (struct testMalloc*) calloc(sizeof(struct testMalloc)); 

You do not need to cast the return value of malloc() or calloc() .

7.

You forgot to check the returned pointed from calloc() for a null pointer if the allocation has failed. Always check the return value of memory-management functions.

test = calloc(1, sizeof(struct testMalloc)); 
if (test == NULL)
{
    fputs("Allocation failed!", stderr);
    // error routine.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM