Search code examples
cprintfdynamic-memory-allocationc-stringsassignment-operator

malloc works with int but not with strings


Im a very new to C language. Im trying to learn about to memory allocation with the next examples.

If I allocate memory for a integer like this:

int* pint = (int*)malloc(sizeof(int));
    
    if (pint == NULL) {
        printf("NULL pointer!");
    } else {
        *pint = 5;
        printf("el valor es: %d", *pint);
        free(pint);
    }

This show perfectly the number 5 and the memory is liberated correctly

But If I try to do the same with a string like this:

char* string = (char*)malloc(sizeof(char)+1);

    if (string == NULL) {
        printf("NULL pointer!");
    } else {
        *string = "Hello World!";
        printf("%s", *string);
        free(string);
    }

Why is that happening and how I can fix it?

thanks in advance

EDIT

Sorry I forgot to show the error that c compiler throws, my bad.

The error is:

warning: assignment to 'char' from 'char *' makes pointer from integer without a cast [-Wint-conversion]

Sorry for my bad english, it isn't my native language. Thanks again.


Solution

  • For starters this memory allocation

    char* string = (char*)malloc(sizeof(char)+1);
    

    does not make sense.

    There are allocated only 2 bytes because sizeof( char ) is always equal to 1.

    If you want to allocate an array that will store the string "Hello World!" then you should write for example

    char *string = malloc( sizeof( "Hello World!" ) );
    

    In this statement

    *string = "Hello World!";
    

    the pointer string is dereferenced. So the left side operand of the assignment statement (the expression *string is equivalent to the expression string[0]) has the type char while the right side operand has the type char[13] (string literals have types of character arrays) that is implicitly converted to pointer to the first element of the string literal of the type char *.

    So in this assignment statement you are trying to assign a pointer to a character. The compiler should issue a message for this statement because there is no implicit conversion from pointers to characters.

    Also in this call of printf

    printf("%s", *string);
    

    you are trying to output a single character *string as a whole string using the conversion specifier %s that results in undefined behavior.

    Instead of this statement

    *string = "Hello World!";
    

    you could write for example

    string = "Hello World!";
    

    That is now the pointer string points to the string literal. And if you will write

    printf("%s", string);
    

    then indeed the string literal will be outputted.

    But that leads to a memory leak because the address of the previously allocated memory will be lost in this case.

    To copy the content of the string literal you should use standard string function strcpy declared in header <string.h>. For example

    char *string = malloc( sizeof( "Hello World!" ) );
    if ( string != NULL ) 
    {
        strcpy( string, "Hello World!" );
        printf( "%s\n", string ); // or just puts( string );
    }