When I run the following code (on Eclipse), I get a pop-up message that the .exe has stop working:
#include <stdio.h>
main ()
{
int x;
x = 1;
printf(x);
}
I know that I should code it as follows in order to make it run:
printf("%d", x);
However, my question is simply what's going on "in there" when I code it the former way.
The printf() first parameter is meant to be a string.
In C, the value '1' is pushed onto the stack to call printf. printf is expecting a string, so it starts to treat 1 as an address.
This causes the "stops working" - when it tries to look at the characters at address 1.
Your code tells printf to print the string at memory address 1.
You probably can't access that, so it crashes.
Related
I wanted to know how the following program is working?
#include <stdio.h>
int main(void) {
while(1){
if(printf("%d",printf("%c")))
break;
else
continue;
}
return 0;
}
I did not know how the part printf("%c") is working and therefore the whole program.I am aware of writing something like printf("%c", 'a'); like that but how is it working without providing the character to be printed? My question is what does the following program prints and how does it prints so?
I have tried to run the program, sometimes it prints nothing, but sometimes it is printing some random character followed by 1. I am not able to get how it is working, can someone please explain what is going behind the code and how it is printing that random characters, and why there is one at the end?
Here are some output I am getting
Welcome to Undefined Behavior. You fail to have sufficient number of arguments for the format you specify, e.g.
C11 Standard - 7.21.6.1 The fprintf function(p2) "If there are insufficient arguments for the format, the behavior is undefined." 7.21.6.1(p9) "If a conversion specification is invalid, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined."
A cool wrong program you have.
printf("%c") attempts to print a single character that is supposed to be the second parameter. However, since you have never passed the second parameter, the function prints whatever is in the register that was supposed to have the second parameter. In other words, some random character. However, it prints one character and returns 1: the number of characters printed.
That 1 is in turn printed by printf("%d",printf("%c")). Now you have a random character followed by 1, and since the outer printf also prints one character, it returns 1.
Finally, if(printf("%d",printf("%c"))) interprets that later 1 as true and breaks the loop.
This is about format bugs.
Look at this code, when execute printf("%d", 123), the program will push number 123 onto the stack, and then push string "%d", when printf meets "%d", it will read the value on the top of the stack, so printf find the number 123.
Now look at this code, printf("%c"), program will push string "%c" onto the stack, and try to read value on the top of the stack, you haven't push a value for printf, so printf will still find value, but the value is random, so you might get a random value.
I was just wondering if you could clear something up for me.
Let's have some example code to explain my question:
#include <stdio.h>
int main(void)
{
char test[100];
printf("%s",test);
return 0;
}
If I am not totally mistaken, this should output randomly either some character that was at this memory address before I declared it or nothing if it was empty like in a virtual environment. So, this is my understanding. The memory held before I put something in is understood as a char and written to the terminal. For instance ascii 'a' = 97 = 01100001. That's why it outputs 'a'. Could have been anything else. Or nothing. And then it stops.
But if I put 'a' in the first position and then print it like this:
test[0] = 'a'
printf("%s",test);
It will output 'a' and additionally to that some character or nothing and then stop.
This is how I understand arrays: An array is a pointer to the first address and the brackets are a dereferences of the address after adding the number times sizeof(type) to it.
So, in that case, the random 01100001 (Ascii 'a') found in the memory in the first example should be indistinguishable for printf from the deliberately placed 01100001 (Ascii 'a') in the second example. Yet, when I run printf, I don't get 100 random outputs. I get one. And I don't assume random fields are in general set to '\0'.
Which means, my understanding must be wrong somewhere. Please help me understand where I make my mistake.
It doesn't, it's undefined behavior. Your program just accidentally prints the un"expected" value.
#include <stdio.h>
int main(void)
{
char test[100];
printf("%s",test);
return 0;
}
You can't expect the code above to do anything predictable, it might print something, it could segfault, there is no way to predict what will actually happen because the behavior of such program is strictly undefined.
int i = 123;
printf("%s\n", i);
I think the complier treats i as the beginning of a string, and trys to find the '\0' to terminate. The process space is read only, so I think it will run successfully. But it prints nothing, and terminated with segmentfault 11.
Your program tried to interpret 123 as a memory address at which to find a string, as specified by the format %s. If you want to print an integer, use %d instead.
What you are getting right now is undefined behaviour, and that is the explanation for why the behaviour is not as you expect.
The following program gives an unexpected output .
#include<stdio.h>
int main()
{
int a=10,b=20;
printf("a=%d",a);
printf(" b=%d");
printf(" %d");
return 0;
}
Why does the above code print:
a=10 b=10 10
The output is same even if I declare b before a, or make 'a' register variable.
According to this post - Behaviour of printf when printing a %d without supplying variable name, a random value from the current stack is printed. But if that was the case, then changing the declaretion styles would result in different results.
So, what is actually happening here?
Function calls are designed so that arguments are always in a pre-defined place. Some older architectures put the arguments on the stack, most new architectures put the arguments in registers.
What's happening here is that the you overwrite the first argument to all the function calls to printf, but the second argument happens to stay unmodified. It's just luck though, anything could have overwritten the place on the stack or the register where the second argument is.
This is the core of undefined behavior in C. Anything could have happened, but usually you can reason about what actually happened. And that's why undefined behavior is so dangerous. Often you end up with behavior that seems predictable and then a minor operating system update or compiler update will change the behavior completely.
put pointer to "a=%d" on the stack, put a on the stack, call printf(), reduce stack-pointer. Then put pointer to " b=%d" on the stack, call printf(), voila, a is still on the stack
i am confused! are all of the following printf's the correct way to print the addresses of functions?
Let me tell you my confusion as well. Everytime i run all of these printf's (that is, 1st printf, 2nd printf and 3rd printf), in output i get
02D4
02D4
02D4
but if i remove or comment of 1st and 2nd printf, i get folowing as output
02BA
when i remove third printf statement, i am getting following output
02D0
Again when i uncomment all of these three, i get:
02D4
02D4
02D4
Why is one statement affecting the output of other printf line?
Is this not really the address of function?
I have heard that s and &s give the same value that is address (just like arrays). but here i am confused why s and &s are affected when i try to print b also, where b=s or &s.
#include<stdio.h>
#include<conio.h>
int s(int);
void main()
{
int a=10,*b;
clrscr();
b=s(a++);
b=&s;
printf("%p\n",s); // 1st printf
printf("%p\n",&s); //2nd printf
printf("%p\n",b); //3rd printf
getch();
}
int s(int x)
{
return x;
}
The address of a variable or a function is not something you can depend on, as both the compiler and the operating system can influence where it ends up.
But supposing that the operating system always loads your executable code at the same address, if you change the length of code in the main() function, that may very well influence the starting address of the s() function. Consequently, you get a different result.