the_daemon_lord
the_daemon_lord

Reputation: 769

Array showing random characters at the end

I wanted to test things out with arrays on C as I'm just starting to learn the language. Here is my code:

#include <stdio.h>
main(){
  int i,t;
  char orig[5];
  for(i=0;i<=4;i++){
    orig[i] = '.';
  }

  printf("%s\n", orig);
}

Here is my output:

.....�

It is exactly that. What are those mysterious characters? What have i done wrong?

Upvotes: 3

Views: 2108

Answers (5)

Rizwan
Rizwan

Reputation: 3666

prinftf takes starting pointer of any memory location, array in this case and print till it encounter a \0 character. These type of strings are called as null terminated strings.

So please add a \0 at the end and put in characters till (size of array - 2) like this :

main(){
  int i,t;
  char orig[5];
  for(i=0;i<4;i++){ //less then size of array -1
    orig[i] = '.';
  }
  orig[i] = '\0'
  printf("%s\n", orig);
}

Upvotes: 1

Sourav Ghosh
Sourav Ghosh

Reputation: 134286

%s with printf() expects a pointer to a string, that is, pointer to the initial element of a null terminated character array. Your array is not null terminated.

Thus, in search of the terminating null character, printf() goes out of bound, and subsequently, invokes undefined behavior.

You have to null-terminate your array, if you want that to be used as a string.

Quote: C11, chapter §7.21.6.1, (emphasis mine)

s

If no l length modifier is present, the argument shall be a pointer to the initial element of an array of character type.280) Characters from the array are written up to (but not including) the terminating null character. If the precision is specified, no more than that many bytes are written. If the precision is not specified or is greater than the size of the array, the array shall contain a null character.

Quick solution:

  • Increase the array size by 1, char orig[6];.
  • Add a null -terminator in the end. After the loop body, add orig[i] = '\0';

And then, print the result.

Upvotes: 7

abhiarora
abhiarora

Reputation: 10430

There is a difference between an array and a character array. You can consider a character array is an special case of array in which each element is of type char in C and the array should be ended (terminated) by a character null (ASCII value 0).

%s format specifier with printf() expects a pointer to a character array which is terminated by a null character. Your array is not null terminated and hence, printf function goes beyond 5 characters assigned by you and prints garbage values present after your 5th character ('.').

To solve your issues, you need to statically allocate the character array of size one more than the characters you want to store. In your case, a character array of size 6 will work.

#include <stdio.h>
int main(){
  int i,t;
  char orig[6]; // If you want to store 5 characters, allocate an array of size 6 to store null character at last position.

  for (i=0; i<=4; i++) {
    orig[i] = '.';
  }

  orig[5] = '\0';

  printf("%s\n", orig);
}

There is a reason to waste one extra character space for the null character. The reason being whenever you pass any array to a function, then only pointer to first element is passed to the function (pushed in function's stack). This makes for a function impossible to determine the end of the array (means operators like sizeof won't work inside the function and sizeof will return the size of the pointer in your machine). That is the reason, functions like memcpy, memset takes an additional function arguments which mentions the array sizes (or the length upto which you want to operate).

However, using character array, function can determine the size of the array by looking for a special character (null character).

Upvotes: 2

ryyker
ryyker

Reputation: 23208

char orig[5];//creates an array of 5 char.  (with indices ranging from 0 to 4)

|?|?|?|0|0|0|0|0|?|?|?|?|
      |         ^memory you do not own (your mysterious characters)
      ^start of orig

for(i=0;i<=4;i++){  //attempts to populate array with '.'
    orig[i] = '.';

|?|?|?|.|.|.|.|.|?|?|?|?|
      |         ^memory you do not own (your mysterious characters)
      ^start of orig

This results in a non null terminated char array, which will invoke undefined behavior if used in a function that expects a C string. C strings must contain enough space to allow for null termination. Change your declaration to the following to accommodate.

char orig[6];

Then add the null termination to the end of your loop:

  ...
  for(i=0;i<=4;i++){
    orig[i] = '.';
  }
  orig[i] = 0;

Resulting in:

|?|?|?|.|.|.|.|.|0|?|?|?|
      |           ^memory you do not own
      ^start of orig

Note: Because the null termination results in a C string, the function using it knows how to interpret its contents (i.e. no undefined behavior), and your mysterious characters are held at bay.

Upvotes: 4

Gangai Johann
Gangai Johann

Reputation: 888

You need to add a NUL character (\0) at the end of your string.

#include <stdio.h>

main()
{
  int  i,t;
  char orig[6];

  for(i=0;i<=4;i++){
    orig[i] = '.';
  }

  orig[i] = '\0';
  printf("%s\n", orig);
}

If you do not know what \0 is, I strongly recommand you to check the ascii table (https://www.asciitable.com/).

Good luck

Upvotes: 1

Related Questions