Different output when printing a null char pointer with and without a newline appended [duplicate] - c

This question already has answers here:
What is the behavior of printing NULL with printf's %s specifier?
(4 answers)
Closed 5 years ago.
I tried the following code on Linux
#include<stdio.h>
int main()
{
char *p=NULL;
printf("%s",p);
return 0;
}
#include<stdio.h>
int main()
{
char *p=NULL;
printf("%s\n",p);
return 0;
}
The first one outputs: (null)
While the second one causes a segmentation fault.
Why does \n make such a difference?

Both of your examples are undefined behavior per standard. Calling printf with %s and passing a NULL pointer is UB.
Therefore it makes no sense to discuss the outcome. On one system you might get one result and on another system you get another result.
Also see https://stackoverflow.com/a/11589479/4386427

Related

Segmentation fault (core dumped) [duplicate]

This question already has answers here:
Why does scanf require &?
(7 answers)
Closed 5 years ago.
Below is a block of code from my program. I'm getting error of Segmentation fault (core dumped) after entering name and age in first loop.
#include<stdio.h>
#include <string.h>
struct Cricketer
{
char name[25];
int age;
float avg_run;
};
int main(){
struct Cricketer c[3];
int i,j;
for (i=0 ; i<3;i++){
printf("Enter name: \n");
scanf("%s",c[i].name);
printf("Enter age: \n");
scanf("%d",c[i].age);
printf("Enter average run: \n");
scanf("%f",c[i].avg_run);
}
return 0;
}
And I couldn't find what is causing this program.
Your error is here:
scanf("%d",c[i].age);
Change it for:
scanf("%d",&(c[i].age));
When using %d you have to pass the address of the int variable. And the same for floats:
scanf("%f",&(c[i].avg_run));
When using scanf, the second argument has to be the address of a variable. With your variable name there is no problem because it already refers to the address of the buffer in which you want to store the string.
When using scanf, the second argument should be the address of a variable. In your program c[i].age and c[i].avg_run are the variables themselves and not the addresses. Use the & operator to get the address of a variable. For Example, &(c[i].age) or just &c[i].age.
What you are passing to scanf as mentioned above are some numbers which might or might not be valid memory addresses. Thus invoking undefined behavior.
c[i].name happens to be fine because referring to an array (name in this case) by just the name evaluates to the base address of the array.
It is a good idea to have compiler warnings enabled. More important is one reads and understands the warnings. Read your compiler manual for more info.

can i see what value of pointing NULL pointer? [duplicate]

This question already has answers here:
What happens in OS when we dereference a NULL pointer in C?
(5 answers)
Closed 6 years ago.
#include<stdio.h>
int main() {
int *p=NULL;
if (p == NULL) {
printf("%x",*p );
}
return 0;
}
If I can, How?
If I can't, What value in it?
No, you cannot in general dereference a NULL pointer, that gives undefined behavior.
That's sort of the point, so this idea is a bit strange.
Note that this doesn't mean that your code won't run on any platform or produce a result, but it still violates the language specification so the result from running it on some particular implementation doesn't matter.

Passing NULL to printf %s [duplicate]

This question already has answers here:
What is the behavior of printing NULL with printf's %s specifier?
(4 answers)
Closed 7 years ago.
#include<stdio.h>
#include<string.h>
int main() {
char *ptr = NULL;
printf("%s", ptr);//The output is null
// printf("%s\n", ptr); //addition of **\n** give segmentation fault
return 0;
}
the first printf outputs: (null). But why the second printf's output is: Segmentation fault (core dumped) just on adding: \n?
printf("%s", ptr);
Here printf expects a valid pointer, which points to null terminated string, you can't pass NULL to it. If you do so, you will trigger undefined behaviour, and can't reason about output of the program.
PS. I have found an answer which might have slightly more details about the thing you might be interested in. See here. Actually your question seems to be a duplicate of that one.
Some printf implementation take care about NULL string parameter, but some of these implementations have "bugs", see gcc printf optimization .
Whatever, C standard says:
the argument shall be a pointer to the initial element of an array of
character type
If not, then it is an undefined behavior. The behavior you've faced is one of these.
The technical reason behind is:
If you write a statement like
printf("%s\n", ptr);
some compilers (i.e. gcc with optimizations) will "optimize" it to:
puts(ptr);
The glibc-implementation of puts() doesn't print (null) on a NULL-pointer (as printf does), but happily segfaults.
When gcc is invoked without optimizations activated, this substitution is not made and printf("%s\n", NULL); will not segfault.
This behaviour is standard compliant, since passing a NULL-pointer to printf() invokes "undefined behaviour".
As i can make out
printf is actually using a system call called write() which will be used by the kernel to write to the stdout file descriptor. In this case the \n causes the pointer to move to unchartered territory and trying to write data from there to the stdout file descriptor causes this behaviour.
Found one good reference from SO itself
C/C++ function definitions without assembly

c string still works when out of boundary? [duplicate]

This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 9 years ago.
who can tell me why the code below still works? it is obvious that the str[4] is out of boundry:
#include<stdio.h>
int main(){
char str[3];
scanf("%s", str);
printf("%c\n", str[4]);
printf("%s\n", str);
return 0;
}
when it runs, enter abcdefg, it will echo the 5th char and the whole string, nothing
will be wrong, weird?
It has been declared that c/c++ doesn't do the boundary checking, while in the case above,
how should I use printf to print a c-string that the user has entered? or more generally, how to properly use a c-string that comes from users?
str[4] gives you a pointer to the memory address after the last element of your string. You can still convert this to a character, but you never know what you get and your software might crash.
Why does it work?
It doesn't "work". It might appear to be working, though; since your code (accessing an array out of bounds) invokes undefined behavior, you can get literally any result. Undefined behavior doesn't mean "it must crash".
You wrote:
when it runs, enter [abcdefg], it will echo the 5th char and the whole
string, nothing will be wrong, weird?
but I see no input reading in the code you posted:
#include<stdio.h>
int main(){
char str[3];
printf("%c\n", str[4]);
printf("%s\n", str);
return 0;
}
In any case, str[4] points to the 5-th char (byte) starting from str, so it will print any "garbage" that happens to be in that memory location when your program runs.
Accessing array items out of bounds is undefined behavior, so the exact behavior is not specified.
Just pay attention to your array bounds.

Increment operator gives segmentation fault? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Change string literal in C through pointer?
Here is a code sample
void main()
{
char *i="prady"; printf("%c ",++*i);
}
Can anyone tell me why this code is giving a segmentation fault in gcc when I guess it should give 'q'. When I am using only *i++ it giving me the result but incase of pre-increment only it's giving me a segmentation fault.
Also tell me why void main is not a proper way to write main() function.
++*i means ++(*i). You're trying to modify the first character of a string literal, which is not permitted. As far as the C standard is concerned behavior is undefined, but this implementation has helpfully segfaulted to alert you to the problem.
*i++ means *(i++). You're modifying your pointer i, which is fine.
void main() is not a proper way to write a main function because the standard says that main returns int. The return value is used to indicate the success or failure of the program. Implementations can support other forms of main, but there are two that are required: int main(void) and int main(int argc, char *argv[]).
++*i
means that you pre-increment your pointer. for example
int *i
*i = 1;
imagine that i is a pointer to the address 0x8FF43FF0
if you compile ++*i before dereferencing i points to 0x8FF43F4
++(*i)
means, first dereference i, than increment
Steve Jessop already told you why ++*i returns an error so I'm not going to tell you that again.
*i++ will return p, the first letter of the word, because the "++" operator returns the value first, and only after had it returned the value does it increment it.
So if you want your program to print 'q' you would have to say printf("%c ",*i+1).
Also, if you want your program to print the second character, try: printf("%c ", *(i+1)). The next letter in the alphabet after the third letter of your word will be printf("%c ", *(i+2)+1) and so on.
Why you should use int main instead of void? The value returned by the main function informs the operating system about how the program ended. o (as in return 0) tells the operating system that the program had executed correctly. you usually use non 0 codes when the program must end because of an error.

Resources