Increment operator gives segmentation fault? [duplicate] - c

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.

Related

Character array initialization in C

I am trying to understand the array concept in string.
char a[5]="hello";
Here, array a is an character array of size 5. "hello" occupies the array index from 0 to 4. Since, we have declared the array size as 5, there is no space to store the null character at the end of the string.
So my understanding is when we try to print a, it should print until a null character is encountered. Otherwise it may also run into segmentation fault.
But, when I ran it in my system it always prints "hello" and terminates.
So can anyone clarify whether my understanding is correct. Or does it depends upon the system that we execute.
As ever so often, the answer is:
Undefined behavior is undefined.
What this means is, trying to feed this character array to a function handling strings is wrong. It's wrong because it isn't a string. A string in C is a sequence of characters that ends with a \0 character.
The C standard will tell you that this is undefined behavior. So, anything can happen. In C, you don't have runtime checks, the code just executes. If the code has undefined behavior, you have to be prepared for any effect. This includes working like you expected, just by accident.
It's very well possible that the byte following in memory after your array happens to be a \0 byte. In this case, it will look to any function processing this "string" as if you passed it a valid string. A crash is just waiting to happen on some seemingly unrelated change to the code.
You could try to add some char foo = 42; before or after the array definition, it's quite likely that you will see that in the output. But of course, there's no guarantee, because, again, undefined behavior is undefined :)
What you have done is undefined behavior. Apparently whatever compiler you used happened to initialize memory after your array to 0.
Here, array a is an character array of size 5. "hello" occupies the array index from 0 to 4. Since, we have declared the array size as 5, there is no space to store the null character at the end of the string.
So my understanding is when we try to print a, it should print until a null character is encountered.
Yes, when you use printf("%s", a), it prints characters until it hits a '\0' character (or segfaults or something else bad happens - undefined behavior). I can demonstrate that with a simple program:
#include <stdio.h>
int main()
{
char a[5] = "hello";
char b[5] = "world";
int c = 5;
printf("%s%s%d\n", a, b, c);
return 0;
}
Output:
$ ./a.out
helloworldworld5
You can see the printf function continuing to read characters after it has already read all the characters in array a. I don't know when it will stop reading characters, however.
I've slightly modified my program to demonstrate how this undefined behavior can create bad problems.
#include <stdio.h>
#include <string.h>
int main()
{
char a[5] = "hello";
char b[5] = "world";
int c = 5;
printf("%s%s%d\n", a, b, c);
char d[5];
strcpy(d, a);
printf("%s", d);
return 0;
}
Here's the result:
$ ./a.out
helloworld��world��5
*** stack smashing detected ***: <unknown> terminated
helloworldhell�p��UAborted (core dumped)
This is a classic case of stack overflow (pun intended) due to undefined behavior.
Edit:
I need to emphasize: this is UNDEFINED BEHAVIOR. What happened in this example may or may not happen to you, depending on your compiler, architecture, libraries, etc. You can make guesses to what will happen based on your understanding of different implementations of various libraries and compilers on different platforms, but you can NEVER say for certain what will happen. My example was on Ubuntu 17.10 with gcc version 7. My guess is that something very different could happen if I tried this on an embedded platform with a different compiler, but I cannot say for certain. In fact, something different could happen if I had this example inside of a larger program on the same machine.

I can't pass the returned character array from a function, as an argument in another function [duplicate]

This question already has answers here:
Return Array in C?
(4 answers)
Closed 5 years ago.
In the following code I want to print a 3*3 matrix with o filled in the boxes. But I don't get the desired output. If you run the program using a C99 compiler the first matrix output is what I expect and the second output is what I get.
If instead of making an initializing function init() if I do the initialization in main() it works fine. But I don't know why the array isn't properly returned from init()so that I can use it as an argument in display() function.
#include<stdio.h>
char * init(int a)
{
char tic[a][a];
for(int i=0;i<=(a-1);i++)
{
for(int j=0;j<=(a-1);j++)
{
tic[i][j]='o';
}
}
display(a,tic);//This is extra code just to show what I desire to print through this program
return (char * )tic;
}
int display(int a,char tic[a][a])
{
for(int i=0;i<=(a-1);i++)
{
for(int j=0;j<=(a-1);j++)
{
if(j==0)
{
printf("\n-------------\n|");
}
printf(" %c |",tic[i][j]);
}
}
printf("\n-------------");
return 0;
}
int main()
{
int a=3;
display(a,init(a));
return 0;
}
According to C11/6.2.4p2:
The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address, and retains its last-stored value throughout its lifetime. If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.
In this case, if you can decipher the entirety of that, you'll have understood what's wrong. Your code uses a pointer which became indeterminate when the function returned, and as a result your code invoked undefined behaviour, and probably crashed.
Call it scope, if you must, but the standard has a different definition for scope, and it is in the standard I place my trust.
My bigger concern is how you got here, with that question, after reading any reasonable educational resource... This seems more like a guess, like you think you can learn C by trial and error. You might get lucky, I suppose, but the odds are heavily stacked against you.
You should read a book, if you aren't already; it'll probably save you many long nights toiling over the evasive bug that disappears when you uncomment the unused variable...
Seems to me that you are trying to pass the return (a character pointer) to a function that asks a different argument (ideally a matrix would be a pointer of character pointer). So, I suggest you to change char * init(int a){ to char ** init(int a) and its return to return (char ** )tic;.
Also, you should change the argument taken from the function display, int display(int a,char tic[a][a]) to int display(int a,char **tic)
Automatic objects ("local variables") go out of scope when the function returns. This means that the tic[] declared in init() no longer exists for the caller (here main()). Technically this means your program invokes undefined behavior.
You need to dynamically allocate the tic array with malloc(). There are good answers here on Stackoverflow how to do that, so don't ask again :-)

Why is this If statement not executing the code? [duplicate]

This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 5 years ago.
I've checked all syntax.
#include <stdlib.h>
#include <stdio.h>
int main(){
char * response;
int anger = 0;
int correct = 0;
printf("type Dice");
scanf("%s", response);
if (response == "Dice"){
printf("Good Job!");
correct = 1;
}
}
I an trying to make a response generator and the is statement isn't working. I tried setting the variable response to the correct answer and the if statement worked so I was thinking that maybe something was wrong with my scanf. I'm a beginner in C.
You did char * response. This makes a pointer variable to a character. Right now it is not pointing to any memory(it is some garbage value). scanf stores user input in consecutive memory addresses starting from the one pointed by response. as response is uninitialised, the input may not necessarily be stored on the stack(Don't want that).
Now when you doresponse=="Dice" it doesn't mean anything at all.
Some pretty basic stuff on arrays and pointers and their comparison.
int arr[10];
now arr points to the first member of the array, arr+1 points to second, arr+2 to third and so on. arr[i] is a shorthand way of saying *(arr+i).
String is also an array of characters.
char *str1="Hello";
char *str2="Hello";
if(str1==str2){...}
What the if statement in line three here does is, it compares to pointers, ie it checks whether they both point to the same location. Since this is not true, execution won't go into the if block. What you want to do is compare the strings character by character. There is an inbuilt function in string.h called strcmp() which does that.
You can't use == to compare strings. Use strcmp() instead. If it returns 0, they're identical.
if (strcmp(response,"Dice")==0){
...
}

Why segmentation fault occur while using pointer variable?

I'm trying to read the paragraph using scanf() function in C.
So, First I tried the below code,
#include <stdio.h>
int main()
{
char Input[100];
printf("Please give the paragraph\n");
scanf("%[^EOF]\n",Input );
printf("\n\n%s\n\n",Input);
return 1;
}
It's working fine, it get the paragraph of input from stdin and print it.
Then I tried the same thing with pointer like given below,
#include <stdio.h>
int main()
{
char *Input;
printf("Please give the paragraph\n");
scanf("%[^EOF]\n",Input );
printf("\n\n%s\n\n",Input);
return 1;
}
This code also get the input and print the output properly.
But it throw the segmentation fault error while the program terminating.
So, I need to know why the error occur while terminating?
If the pointer doesn't point any memory means, How the printf() is printing the given input, and from where it is printing?
Thanks.
Since Input is a pointer to nothing in particular and has no value in particular, passing its value to scanf makes no sense. Assign it a value first -- make it point to something -- and then you can use it to tell scanf where to store things.

Why such an output

I executed this code after compiling in codeblocks:-
#include <stdio.h>
int main()
{
char arr[]="HELLO";
int a=arr;
return printf("...%s ,%s\n",arr,&a+1);
}
I got this output:-
...HELLO,HELLO
when I changed &a to a,printf returned -1.
I am not able to sort out this address logic ,please help.
(A friend gave me this code and asked its explanation, and I am not able to find it). So I would like to know why..
Thanks
You are telling printf to expect a string, but you are giving it the address of an int (&a). This invokes undefined behaviour, so anything could happen.
[In practice, what's probably happening is that the compiler places a directly below arr on the stack. So &a+1 ends up equal in value to &arr. printf then reinterprets that address as a pointer-to-char, and so ends up printing HELLO. If the compiler happened to arrange the stack differently, you'd observe different behaviour.]

Resources