Home > Software design >  C printf prints an array that I didn't ask for
C printf prints an array that I didn't ask for

Time:07-23

I have recently started learning C and I got into this problem where printf() prints an array I didn't ask for. I was expecting an error since I used %s format in char array without the '\0', but below is what I got.

char testArray1[] = { 'a','b','c'};
char testArray2[] = { 'q','w','e','r','\0' };

printf("%c", testArray1[0]);
printf("%c", testArray1[1]);
printf("%c\n", testArray1[2]);

printf("%s\n", testArray1);

the result is

abc
abcqwer

thanks

CodePudding user response:

The format "%s" expects that the corresponding argument points to a string: sequence of characters terminated by the zero character '\0'.

printf("%s\n", testArray1);

As the array testArray1 does not contain a string then the call above has undefined behavior.

Instead you could write

printf("%.*s\n", 3,testArray1);

or

printf("%.3s\n", testArray1);

specifying exactly how many elements of the array you are going to output.

Pay attention to that in C instead of these declarations

char testArray1[] = { 'a','b','c'};
char testArray2[] = { 'q','w','e','r','\0' };

you may write

char testArray1[3] = { "abc" };
char testArray2[] = { "qwer" };

or that is the same

char testArray1[3] = "abc";
char testArray2[] = "qwer";

In C the first declaration will be invalid.

CodePudding user response:

%s indeed stop when encountered \0, but testArray1 didn't have that \0, so it keeps printing the following bytes in the memory.

And the compiler magically(actually intentionally) places the testArray2 next to testArray1, the memory is like:

a b c q w e r \0
^                testArray1 starts here
      ^          testArray2 starts here

And the %s will print all of those chars above until it meets a \0.

You can validate that by:

printf("%d\n", testArray2 == testArray1   3);
// prints `1`(true)

As your question, there was no error because the a ... r \0 sequece in memory is owned by your process. Only the program is trying to access an address not owned by it, the OS will throw an error.

CodePudding user response:

Add zero at the end of first array:

char testArray1[] = { 'a','b','c', 0 };

Otherwise printf continues with memory after 'c' until zero byte and there is the second array.

PS: zero 0 is 100% identical to longer ASCII '\0'.

  • Related