C char array initialization

CArraysCharInitializationBuffer

C Problem Overview


I'm not sure what will be in the char array after initialization in the following ways.

1.char buf[10] = "";
2. char buf[10] = " ";

  1. char buf[10] = "a";

For case 2, I think buf[0] should be ' ', buf[1] should be '\0', and from buf[2] to buf[9] will be random content. For case 3, I think buf[0] should be 'a', buf[1] should be '\0', and from buf[2] to buf[9] will be random content.

Is that correct?

And for the case 1, what will be in the buf? buf[0] == '\0' and from buf[1] to buf[9] will be random content?

C Solutions


Solution 1 - C

This is not how you initialize an array, but for:

  1. The first declaration:

     char buf[10] = "";
    

    is equivalent to

     char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  2. The second declaration:

     char buf[10] = " ";
    

    is equivalent to

     char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  3. The third declaration:

     char buf[10] = "a";
    

    is equivalent to

     char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    

As you can see, no random content: if there are fewer initializers, the remaining of the array is initialized with 0. This the case even if the array is declared inside a function.

Solution 2 - C

  1. These are equivalent

     char buf[10] = "";
     char buf[10] = {0};
     char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  2. These are equivalent

     char buf[10] = " ";
     char buf[10] = {' '};
     char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  3. These are equivalent

     char buf[10] = "a";
     char buf[10] = {'a'};
     char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    

Solution 3 - C

Edit: OP (or an editor) silently changed some of the single quotes in the original question to double quotes at some point after I provided this answer.

Your code will result in compiler errors. Your first code fragment:

char buf[10] ; buf = ''

is doubly illegal. First, in C, there is no such thing as an empty char. You can use double quotes to designate an empty string, as with:

char* buf = ""; 

That will give you a pointer to a NUL string, i.e., a single-character string with only the NUL character in it. But you cannot use single quotes with nothing inside them--that is undefined. If you need to designate the NUL character, you have to specify it:

char buf = '\0';

The backslash is necessary to disambiguate from character '0'.

char buf = 0;

accomplishes the same thing, but the former is a tad less ambiguous to read, I think.

Secondly, you cannot initialize arrays after they have been defined.

char buf[10];

declares and defines the array. The array identifier buf is now an address in memory, and you cannot change where buf points through assignment. So

buf =     // anything on RHS

is illegal. Your second and third code fragments are illegal for this reason.

To initialize an array, you have to do it at the time of definition:

char buf [10] = ' ';

will give you a 10-character array with the first char being the space '\040' and the rest being NUL, i.e., '\0'. When an array is declared and defined with an initializer, the array elements (if any) past the ones with specified initial values are automatically padded with 0. There will not be any "random content".

If you declare and define the array but don't initialize it, as in the following:

char buf [10];

you will have random content in all the elements.

Solution 4 - C

The relevant part of C11 standard draft n1570 6.7.9 initialization says:

> 14 An array of character type may be initialized by a character string literal or UTF-8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

and

> 21 If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

Thus, the '\0' is appended, if there is enough space, and the remaining characters are initialized with the value that a static char c; would be initialized within a function.

Finally,

> 10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static or thread storage duration is not initialized explicitly, then:

> [--]

> - if it has arithmetic type, it is initialized to (positive or unsigned) zero;

> [--]

Thus, char being an arithmetic type the remainder of the array is also guaranteed to be initialized with zeroes.

Solution 5 - C

Interestingly enough, it is possible to initialize arrays in any way at any time in the program, provided they are members of a struct or union.

Example program:

#include <stdio.h>

struct ccont
{
  char array[32];
};

struct icont
{
  int array[32];
};

int main()
{
  int  cnt;
  char carray[32] = { 'A', 66, 6*11+1 };	// 'A', 'B', 'C', '\0', '\0', ...
  int  iarray[32] = { 67, 42, 25 };

  struct ccont cc = { 0 };
  struct icont ic = { 0 };

  /*  these don't work
  carray = { [0]=1 };			// expected expression before '{' token
  carray = { [0 ... 31]=1 };	// (likewise)
  carray = (char[32]){ [0]=3 };	// incompatible types when assigning to type 'char[32]' from type 'char *'
  iarray = (int[32]){ 1 };		// (likewise, but s/char/int/g)
  */

  // but these perfectly work...
  cc = (struct ccont){ .array='a' };		// 'a', '\0', '\0', '\0', ...
  // the following is a gcc extension, 
  cc = (struct ccont){ .array={ [0 ... 2]='a' } };	// 'a', 'a', 'a', '\0', '\0', ...
  ic = (struct icont){ .array={ 42,67 } };		// 42, 67, 0, 0, 0, ...
  // index ranges can overlap, the latter override the former
  // (no compiler warning with -Wall -Wextra)
  ic = (struct icont){ .array={ [0 ... 1]=42, [1 ... 2]=67 } };	// 42, 67, 67, 0, 0, ...

  for (cnt=0; cnt<5; cnt++)
    printf("%2d %c %2d %c\n",iarray[cnt], carray[cnt],ic.array[cnt],cc.array[cnt]);

  return 0;
}

Solution 6 - C

I'm not sure but I commonly initialize an array to "" in that case I don't need worry about the null end of the string.

main() {
    void something(char[]);
    char s[100] = "";

    something(s);
    printf("%s", s);
}

void something(char s[]) {
    // ... do something, pass the output to s
    // no need to add s[i] = '\0'; because all unused slot is already set to '\0'
}

Solution 7 - C

I use below format when I use strings etc

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



void func(char *str)
{
       char str1[50]={'\0'};
       int length=0;           
        
       if ((strlen(str) + 1) > 50)
                fprintf(stderr, "string too long\n");
       else if (str == NULL)
                fprintf(stderr, "Invalid pointer\n");
       else {
                memcpy(str1, str, strlen(str) + 1);
                if(*str1 == '\0' )
                        fprintf(stderr, "Invalid string\n");
                else         
                        printf("--> %s\n", str1);
               
                memset(str1 ,'\0' , strlen(str1) + 1);
                str=NULL;
       }
}

int main()
{
        func("this is my string");
        return 0;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionlkkeepmovingView Question on Stackoverflow
Solution 1 - CouahView Answer on Stackoverflow
Solution 2 - CZomboView Answer on Stackoverflow
Solution 3 - CverboseView Answer on Stackoverflow
Solution 4 - CAntti Haapala -- Слава УкраїніView Answer on Stackoverflow
Solution 5 - Cuser3381726View Answer on Stackoverflow
Solution 6 - CErric RapsingView Answer on Stackoverflow
Solution 7 - CmrigendraView Answer on Stackoverflow