Simple Issue with Arrays - c

I was just wondering why the output for this code I have below is abcdef def instead of abc def.
main()
{
char array1[3]="abc";
array1[3]='\0';
char array2[3]="def";
array2[3]='\0';
printf("%s %s", array1, array2);
}

char array1[3]="abc";
array1[3]='\0';
char array2[3]="def";
array2[3]='\0';
array1[3]='\0'; and array2[3]='\0'; statements access arrays out of bounds and invoke undefined behavior. The last element of an array of 3 elements is array1[2] not array[3].
To fix your program, declare your arrays as:
char array1[]="abc";
char array2[]="def";
And don't manually add the null terminator as it will be already included in the declaration above.
EDIT:
some other answers incorrectly assume that
char array1[3]="abc";
would write a trailing null character outside the array. Actually no trailing null character is written in this initialization. The declaration is equivalent to:
char array1[3]= {'a', 'b', 'c'};

When you do:
char array1[3]="abc";
Then array1[3] is out of bounds.
You should do:
char array1[4]="abc"; //Remember the '\0'
^^^
Note that the '\0' will be added in this way.
Also please note that when you have array of size N, then the indexes are from 0 to N - 1.

In your code
main()
{
char array1[3]="abc"; //Undefined ,when you access this using printf() with %s
array1[3]='\0'; //here you are storing value which is out of bound in nature
char array2[3]="def"; //same as above
array2[3]='\0'; //same as above
printf("%s %s", array1, array2);
}
memory:
---------------
| a | b | c |\0|
----------------
The last \0 what you are putting is more than the space you have allocated.
solution:
main()
{
char array1[4]="abc";
//array1[3]='\0'; //no need
char array2[4]="def";
// array2[3]='\0'; //no need
printf("%s %s", array1, array2);
}
It will give desired output

This is such a bad code! What is happening is the following:
Compiler allocated space for 2x3 chars.
main()
{
char array1[3]="abc"; //Will write "abc" in array 1 AND \0 in array2[0]
array1[3]='\0'; //Out of array!!! (Re)writing \0 in array2[0]
char array2[3]="def"; //Will write "def" in array2 AND \0 after array2 space, POTTENCIALLY corrupting code!
array2[3]='\0'; //\0 (re)wrote after array2, POTTENCIALLY corrupting code!
What you have in memory is 7 bytes (just 6 were allocated): "abcdef\0".
Pointes still ok: array1 points "a" and array2 points "d".
In C standard libraries, strings sizes are determined by ending zero terminator. So when you printf array1, it will read "abcdef" until \0.

Related

Printf function prints another string too

Hi i am fairly new in C language and i was trying to understand the strings. As i know, strings are just an array of characters and there shouldn't be a difference between char a[]= "car" and char a[] = {'c','a','r'}.
When i try to print the string as:
char a[] = "car";
char b[] = "testing the cars";
printf("%s", a);
the output is just car and there's no problem.But when i try to print it as:
char a[] = {'c','a','r'};
char b[] = "testing the cars";
printf("%s", a);
it's printing the b too. Can you explain what's the reason of it?
The %s specifier of printf() expects a char* pointer to a null-terminated string.
In the first case, a and b are both null-terminated. Initializing a char[] array of unspecified size with a string literal will include the literal's null-terminator '\0' character at the end. Thus:
char a[] = "car";
is equivalent to:
char a[] = {'c', 'a', 'r', '\0'};
In the second case, a is NOT null-terminated, leading to undefined behavior, as printf("%s", a) will read past the end of a into surrounding memory until it eventually finds a '\0' character. It just happens that, in your case, b exists in that memory following a, but that is not guaranteed, the compiler can put b wherever it wants.

Why it shows two arrays rather than one array

I am a beginner of c. Today when i write a c program, I find some strange thing.
What i want it to show is abc, but it show abcefg. I want to know why it's so shown.
the code is:
#include <stdio.h>
int main() {
char a[3] = "abc";
char b[3] = "efg";
printf("%s", a);
return 0;
}
It's answer is not abc but abcefg
Strings in C are zero terminated with '\0'. "abc" actually is { 'a', 'b', 'c', '\0' }, which is 4 chars. Your array a only has room for 3 chars so the '\0' isn't stored. When printf() tries to print the string stored in a it reads and prints one character a time until it encounters a terminating '\0', but there is none. So it continues reading and printing. And it happens that b is right next to a in memory, so the content of b gets printet as well.
Cure:
#include <stdio.h>
int main(void)
{
char a[4] = "abc";
char b[4] = "efg";
printf("%s", a);
}
or, even better, don't specify a size for the arrays at all. Let the compiler figure out the correct size based on the initializer "abc":
#include <stdio.h>
int main(void)
{
char a[] = "abc";
char b[] = "efg";
printf("%s", a);
}
char a[3] = "abc"; misses space for the 0-terminator, so printf will read out of bounds (undefined behavior) into the next memory location , where it finds the b array (by luck).
You should use char a[4] = "abc"; or char a[] = "abc";.
When you do not write an array size, the compiler will evaluate the minimum size from the initialization.
char b[3] = "efg"; has the same problem, but it seems that you are lucky enough to have a 0 byte afterwards.

Printing an array of characters

I have an array of characters declared as:
char *array[size];
When I perform a
printf("%s", array);
it gives me some garbage characters, why it is so?
http://www.cplusplus.com/reference/clibrary/cstdio/printf/
This url indicates printf takes in the format of: `int printf ( const char * format, ... );
#include <stdio.h>
#include <string.h>
#define size 20
#define buff 100
char line[buff];
int main ()
{
char *array[100];
char *sep = " \t\n";
fgets(line, buff, stdin);
int i;
array[0] = strtok(line, sep);
for (i = 1; i < size; i++) {
array[i] = strtok(NULL, sep);
if (array[i] == NULL)
break;
}
return 0;
}
You declare an array of characters like so:
char foo[size];
You seem to have it mixed up with char *, which is a pointer to a character. You could say
char *bar = foo;
which would make bar point to the contents of foo. (Or, actually, to the first character of foo.)
To then print the contents of the array, you can do one of the following:
// either print directly from foo:
printf("%s", foo);
// or print through bar:
printf("%s", bar);
Note, however, that C performs no initialization of the contents of variables, so unless you specifically set the contents to something, you'll get garbage. In addition, if that garbage doesn't happen to contain a \0; that is, a char with value 0, it will keep on outputting past the end of the array.
Your array is not initialized, and also you have an array of pointers, instead of an array of char's. It should be char* array = (char*)malloc(sizeof(char)*size);, if you want an array of char's. Now you have a pointer to the first element of the array.
Why are we making such a simple thing sound so difficult?
char array[SIZE];
... /* initialize array */
puts(array); /* prints the string/char array and a new line */
/* OR */
printf("%s", array); /* prints the string as is, without a new line */
The char in array after the end of what you want to be your string (ie. if you want your string to read "Hello" that would be the next char after the 'o') must be the terminating NUL character '\0'. If you use a C function to read input that would automatically be appended to the end of your buffer. You would only need to worry about doing it manually if you were individually writing characters to your buffer or something for some reason.
EDIT: As with pmg's comment, the '\0' goes wherever you want the string to end, so if you wanted to shorten your string you could just move it up closer to the front, or to have an empty string you just have array[0] = '\0';. Doing so can also be used to tokenise smaller strings inside a single buffer, just as strtok does. ie. "Part1\0Part2\0Part3\0". But I think this is getting away from the scope of the question.
ie. you wanted to store the first 3 chars of the alphabet as a string (don't know why anyone would do it this way but it's just an example):
char array[4];
array[0] = 'a';
array[1] = 'b';
array[2] = 'c';
array[3] = '\0';
printf("%s\n", array);
If you have something like char array[] = "Hello"; the '\0' is automatically added for you.
char *array[size];
array is not a char * with that, it's more like a char ** (pointer to an array of chars, with is similar to pointer to pointer to char).
If all you need is a C string, either:
char array[size];
and make sure you 0-terminate it properly, or
char *array;
and make sure you properly allocate and free storage for it (and 0-terminate it too).

Printf(" ABCD" ); printf("ABCD" +1);

void main()
{
printf("ABCD");
printf("\n");
printf("ABCD" +1);
printf("\n");
printf("ABCD" +3);
}
Outputs is:
ABCD
BCD
D
Can anyone explain me why?
"ABCD" is actually an array of characters {'A','B','C','D', '\0'} (where '\0' is the trailing null byte). If you add 3 to that, then that is the equivalent of advancing a pointer 3 bytes forward from A, so you end up pointing at D.
Question 6.2 in the C FAQ has a picture that makes this clearer. The array decays to a pointer as described in 6.4 so you have the situation of the variable p.
char a[] = "hello";
char *p = "world";
"ABCD" is treated as a pointer to a block of memory containing four characters followed by a null terminator (\0).
"ABCD" + 1 adds 1 to the pointer, causing it to point one byte further.

Some 'predict the outputs' with pointers

Help me in solving 2 questions on pointers:
1)Please tell me why do I get 'segmentation fault' when I run following snippet
main()
{
char *str1 = "united";
char *str2 ="front";
char *str3;
str3 = strcat(str1,str2);
printf("\n%s",str3);
}
2)Why don't I get output in following code:
main()
{
char str[10] = {0,0,0,0,0,0,0,0,0,0};
char *s;
int i;
s = str;
for(i=0 ; i<=9;i++)
{
if(*s)
printf("%c",*s);
s++;
}
}
Thank u.
You should review how strcat works. It will attempt to rewrite the memory at the end of your str1 pointer, and then return the destination pointer back to you. The compiler only allocated enough memory in str1 to hold "united\0" (7 chars), which you are trying to fill with "unitedfront\0" (12 chars). str1 is pointing to only 7 allocated characters, so there's no room for the concatenation to take place.
*s will dereference s, effectively giving you the first character in the array. That's 0, which will evaluate to false.
1) compiles to something like:
const char _str1[7] = "united";
const char _str2[6] ="front";
char *str1 = _str1;
char *str2 = _str2;
strcat(str1,str2);
str3 = str1;
str1 points to a buffer which is exactly 7 bytes long and is filled with 6 characters. The strcat put another 5 bytes into that buffer. 7 bytes cannot hold 11 characters.
The C there is no magic! If you do not explicitly allocate space for something, no one else does it either.....
2) isn't going to print anything. It steps through an array, every element of which is 0. It then tests if the current item (*s) is not 0 (if(*s)) , and if so, prints that item as a character. However, since the item always is 0, it always fails to test.
for question 2, think about what the following line does:
if(*s)

Resources