user13243126
user13243126

Reputation:

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;

Upvotes: 1

Views: 1008

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 310920

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

Upvotes: 3

Some programmer dude
Some programmer dude

Reputation: 409136

The problem seems that you attempt to free memory that wasn't allocated with malloc.

In C all literal strings are really stored (by the compiler) as arrays of non-modifiable characters.

When you have

char * result = "";

the compiler will create such an array for the empty string. It will contain one single element, the string null terminator. The initialization will make result point to the first element of that array.

And like any other array, you can't free it.

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

is basically the same as

char array[] = "";
char * result = array;
free(result);

It just makes no sense.

That is works with

char * result = '\0';

is because (as explained) that initializes result as a null pointer, and it's valid to pass a null pointer to free (it is a no-op).

Upvotes: 0

Related Questions