Search code examples
cpointersinitializationfreestring-literals

Should a null character string be equal to a null-terminator in C?


Is there a difference between initializing a character array with null characters and with a null terminator ? These two examples:

char * result = ""
char * result = '\0';

The first one gives me an error but the other one is passable.

Function prototype:

char * form(int n, ...);

The code is:

char * result = "";
char *next;
char val_int[12];
int i;
va_list args;
va_start(args, n);

for (i = 0; i < n; i++)
{
    int len = result ? strlen(result) : 0;
    sprintf(val_int, "%d", va_arg(args,int));
    next = val_int;
    char *tmp = (char *)malloc(len + strlen(next) + 1);

    strcpy(tmp, result ? result : "");
    strcat(tmp, next);

    free(result);
    result = tmp;
}
va_end(args);
return result;

Main function:

  char *s;
  s = form(3,123,456,789);
  printf("%s", s);
  free(s);
  return 0;

Solution

  • The first declaration

    char * result = "";
    

    declares a pointer to the string literal that contains one character: the terminating zero '\0'.

    This declaration

    char * result = '\0';
    

    initialize the pointer by a null pointer constant and is equivalent to

    char * result = NULL;
    

    Here is a demonstrative program

    #include <stdio.h>
    
    int main(void) 
    {
        char *s1 = "";
        char *s2 = '\0';
    
        printf( "s1 == NULL is %s\n", s1 == NULL ? "true" : "false" );
        printf( "s2 == NULL is %s\n", s2 == NULL ? "true" : "false" );
    
        return 0;
    }
    

    Its output is

    s1 == NULL is false
    s2 == NULL is true
    

    As for the error you are saying about then its reason is this statement

    free(result);
    

    You may not free a memory occupied by a string literal. You may free a memory that was allocated dynamically.

    When there is used a pointer initialized by the character literal '\0' then such a pointer is a null pointer and you may call free for a null pointer.

    That is if you have a pointer initialized like

    char * result = NULL;
    

    that is the same as to write

    char * result = '\0';
    

    then you may call

    free( result );
    

    No action will be performed by such a call.

    But if you will write

    free( "" );
    

    trying to free a string literal that has static storage duration you will get undefined behavior.

    And this call

    free( "" );
    

    is equivalent to the following code snippet

    char * result = "";
    free( result );