1

/* what i observed is :

  1. when i give string like "ab" to b(array)
    then the output is : "ab" "help" "dude"
  2. when i give "abc"
    then output is : "abc" " " "dude"
  3. if i give "abcd" then output is : "abc" "d" "dude"

    so on */

       #include<stdio.h>
       main()
       {
            char a[5]="help",b[3],c[10]="dude";
         scanf("%s",b);
         printf("\t%s",b); 
         printf("\t%s",a);
         printf("\t%s",c);
       }
    
       /* what i dont get is :
        Here iam  gaving a string to b(array),  why, if the string has more than the  
        required no. of charecters, its printing those charecters in other arrays 
       (though i had not assiged scanf to other arrays )?   
    
5
  • 1
    It's undefined behaviour. Commented Oct 19, 2013 at 5:41
  • what!! i didnt get it? Commented Oct 19, 2013 at 5:42
  • scanf("%s",&b); you don't need an &, b is already a pointer Commented Oct 19, 2013 at 5:45
  • 1
    @AlterMann: b is an array, which degrades to a pointer under certain circumstances. Let's not tell a beginner that arrays and pointers are the same thing. OP, undefined behavior means that the behavior of your code is... undefined. You are doing something illegal (writing past the end of an array), which leaves your program in an undefined state. In this instance, it ends up writing into the memory used to store another array. Commented Oct 19, 2013 at 5:45
  • Ed, you are right, b decays into a pointer Commented Oct 19, 2013 at 5:47

7 Answers 7

5

Remember that a string in C needs space for a null terminator. If there is no space, printing will continue "to the next nul". Here is how your memory looks at initialization:

h  e  l  p \0 \0 \0 \0  d  u  d  e \0
^             ^         ^
a             b         c

When you read in a string ab in the location pointed to by b:

h  e  l  p \0  a  b \0  d  u  d  e \0
^              ^        ^
a              b        c

And all is well. But abc gives:

h  e  l  p \0  a  b  c \0  u  d  e \0
^              ^        ^
a              b        c

and when you print b you will get abc; printing c will get you nothing (first character is '\0').

Finally, with an input of abcd you get

h  e  l  p \0  a  b  c  d \0  d  e \0
^              ^        ^
a              b        c

And printing c will result in "d" - exactly as you are seeing.

In fact, the order in which things are stored in memory is not "defined", although usually the compiler will do something similar to the above. So while you know that you can't write to memory that isn't yours, you can't be sure what will happen when you do (as in your case). That is why it is called "undefined behavior". You can't rely on other compilers giving you the same result - or even the same compiler giving you the same result...

Make sense?

The solution, of course, is to allocate more space to b. That would result in more '\0' between b and c, and nothing gets overwritten.

edit - I did just realize that it seems that the order in which b and a are stored is backwards from how I just described it - because it's a, not c that is getting overwritten. Which shows that the compiler orders things as it jolly well pleases, and that I ought to wear my glasses when I write detailed answers. But the principle is exactly the same - so I will "leave the rest as an exercise for the student".

Sign up to request clarification or add additional context in comments.

2 Comments

So what you are saying is some compilers assaign arrays side by side and if i give extra data then it overwrite the date adjacent to it, Right?
@Srinadh - yes that is exactly what I am saying.
1

Your arrays are placed in memory in the following order

c[10], b[3], a[5]

So if array b will contain more characters than it can accomodate then some its characters will overlap array a, Consider these two arrays, b and a, as they are in memory

b[0] b[1] b[2] a[0] a[1] a[2] a[3] a[4]

When you eneters "abc" in b you got

b[0] b[1] b[2] a[0] a[1] a[2] a[3] a[4]
'a'  'b'  'c'  '\0' 'e'  'l'  'p'  '\0'

So after executing the statements

 printf("\t%s",b); 
 printf("\t%s",a);

the output is

"abc" ""

because a[0] contains '\0'

When you entered "abcd" you got

b[0] b[1] b[2] a[0] a[1] a[2] a[3] a[4]
'a'  'b'  'c'  'd' '\0'  'l'  'p'  '\0'

and the output is

"abcd" "d"

because a[0] contains 'd' and a[1] contains '\0'

Comments

0

b[3] is an array of 3 characters. However the string abc is made of 4 characters, the last one being \0, indicating end of the string. So if you want be to be able to store abc, you need to declare at least an array of 4 characters, not 3

1 Comment

ok i edited that &b; but i want to know is address of a,b,c are each different when i call printf with relation to arrays then it should print, what the data stored in then,, here rather its printing the data that i gave to b, leaving to call the other array say a, and thats my question why its happening like that
0

when you give abc as input your array b gets filled up(as it has only 3 places ) and has no space left for \0character. As a result when you try to print it out as a string .. it overflows and causes the error

For a string to be printable, it has to be of the following format: stringtext\0 but when you use up all the spaces in your array b you leave no space for \0 as a result when you print it , there is error

Also this statement is wrong in your code :

scanf("%s",&b);

it should be :

scanf("%s",b);

2 Comments

ok i edited that &b; but i want to know is address of a,b,c are each different when i call printf with relation to arrays then it should print, what the data stored in then,, here rather its printing the data that i gave to b, leaving to call the other array say a, and thats my question why its happening like that
@Srinadh .. i didn't understand your question
0

So what's really happening is you are going outside the end of your arrays and overwriting memory.

When you provide 'ab' as input to b, it works because b is large enough to store 'ab' and the \0 as others have mentioned.

When you provided 'abc' as input, b does not have enough space allocated to store abc and the null so it only stores 'abc' and then the null appears to get written to the first byte of the a array, which means it's just an empty string... or maybe it doesn't, this is the undefined part. Who knows what is stored outside your array. It just so happens you are probably getting lucky since those arrays you have defined are most likely in contiguous memory.

When you provide 'abcd' as input, the d and the null get written to the a array.

Many times in less-simple programs, you'll get a SEGV with programming errors like this.

Comments

0

This is simply one of the case of undefined behavior. b[3] can store a string of three characters (including \0), but when your input is abc it is of four character string and you can't store it in array b. You will get anything.

Comments

0

When you place "abc" into b[3], it's going past the end of the array. The abc string is four bytes since it has a nul terminator at the end.

Since it's undefined behaviour, anything can technically happen but what's actually happening is that the nul at the end of the string is overwriting the first character of the next variable in memory, rendering it an empty string.

Quickest solution is to ensure your character array are big enough to store all the characters plus the terminator:

char b[4] = "abc";

Or let the compiler handle it for this particular simple case:

char b[] = "abc";

2 Comments

ok i edited that &b; but i want to know is address of a,b,c are each different when i call printf with relation to arrays then it should print, what the data stored in then,, here rather its printing the data that i gave to b, leaving to call the other array say a, and thats my question why its happening like that
@Srinadh, I didn't mention the addressof operator. All you need to do is make sure your arrays are big enough.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.