menu

Questions & Answers

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.

Comments:
2023-01-11 09:12:51
Hint: *string = "Hello World!"; is not how you do it. See: strcpy().
2023-01-11 09:12:51
Tip: You'll need to brush up on what is and isn't copyable via * dereferencing. int* is a trivial copy, and char* would work, if you were copying a single char.
2023-01-11 09:12:51
More hints: "Hello World!" doesn't fit in 2 bytes
2023-01-11 09:12:51
Doing *string returns the first char of string, but printf needs a char * for %s. So, you want: printf("%s",string); But, your malloc only allocates space for one byte--not enough space for a string which needs space for the EOS (0x00) terminator. The TL;DR is: forego the malloc and change *string = "Hello World!" --> string = strdup("Hello World!");
2023-01-11 09:12:51
You can/should look up the documentation for strdup. But, the code you'll need is something akin to it. Here's a simple example: char * strdup(const char *str) { size_t len = strlen(str) + 1; char *dup = malloc(len); if (dup != NULL) memcpy(dup,str,len); return dup; }
2023-01-11 09:12:51
sizeof(char) is defined to be exactly 1 - always!
Answers(2) :

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 );
}
 

The statement;

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

allocates memory for only 2 bytes.


Then:

*string = "Hello World!";

doesn't copy the string literal "Hello World! to string.

The C standard library provides strcpy to copy two strings. You could also use POSIX's strdup.


Incorrect argument to printf:

printf("%s", *string);

%s format specifier expects a char *, *string produces a char.

Change it to:

printf("%s", string);

Aside: Casting the result of malloc and family is redundant and could hide a bug. These functions return a void * which is automatically promoted to the correct type.