Why segmentation fault occur while using pointer variable? - c

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.

Related

The printf function in C is not working as intended [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Can someone help me with this issue? For some reason, no matter what I try, doing printf isn't printing in my code. I've been trying to use the flush method, but that seems to just cause other issues. Is there anything else I can do?
int main(void) {
char **line;
size_t bufsize=MAXBUF;
printf("Type your name: ");
getline(&line,&bufsize,stdin);
}
You are trying to pass in an empty pointer, this pointer isn't pointing to any meaningful address at the start of the program. So the problem with this is that even if you were successful, it would overwrite some random address in memory with the input, and this is almost certainly what you don't want as it will cause a segmentation fault or a crash.
However that's not the reason why it's not compiling. It's not compiling because you are trying to pass in char *** to a function that expects char **.
So what I would do is:
#include <stdio.h>
int main(void) {
char *line=NULL;
size_t bufsize=0;
printf("Type your name: ");
if(getline(&line,&bufsize,stdin)==-1){
puts("Error: User cancelled input.");
}
else{
printf("Entered: %s",line);
}
free(line);
return 0;
}
So what this code does is that it creates a pointer to an array of characters but it sets the pointer to point to NULL so that the program can see it's not pointing anywhere, and then its address (&line) is given to the getline function, this turns the char * type into a char ** which is required by the getline function. Whenever you put a & in front of something in C, it adds an extra * to the type.
You probably know this already, but if a function states that it returns something, you should always return something, even if it's nonsense otherwise depending on the type that should be returned, that can sometimes cause a crash.
There was nothing wrong with your use of printf, that was fine. printf doesn't necessarily fflush to stdout, often the \n character will trigger a flush, but it's implementation specific, so if your program crashes before an fflush is written to stdout, then you may never see the last printf. You can try an fflush(stdout); before the getline function, but after the getline function may not work because it may crash before then.
In your case what's happening is that before the printf writes to the screen the getline takes in the address of the pointer (or pointer to a pointer), dereferences it to a pointer, isn't able to, so before you have a chance to enter in any keystrokes it crashes, losing the stdout pipe, so you end up never seeing your prompt.
When i run the altered code, above, i get:
XXXX#dell:~$ gcc Deleteme.c
XXXX#dell:~$ ./a.out
Type your name: test1
Entered: test1
XXXX#dell:~$
And it runs correctly under Linux. The key lesson in all this is that, terminals are slow to update on the screen, so some time in the past, the decision was made to separate out the functionality of printf.
There are two components to printf:
The part that writes the text to stdout.
The part that updates the terminal with stdout (the flush).
This question is interesting because 1) succeeded, but the system crashed before 2) was completed.
The documentation for getline says the first parameter must be a char **, but you pass it the address of line. Since line is a char **, &line is a char ***, which is the wrong type.
getline() allocates and re-allocates memory. The address of the length and the buffer need to reflect that.
int main(void) {
char *line = NULL;
size_t bufsize = 0;
printf("Type your name: ");
fflush(stdout); // Flush output before reading.
ssize_t len = getline(&line, &bufsize, stdin);
if (len < 0) Handle_error_with_code();
...
free(line); // When done, free memory
}
There is no need to allocate any memory before calling getline().
getline() expects line, bufsize to reflect allocated data via malloc() and friends. It is easy enough to start with NULL, 0 here.
First you are passing the address of line to the getline(), the documentation says that the first argument is the address of the first character position where the input string will be stored. It’s not the base address of the buffer, but of the first character in the buffer.
This pointer type (a pointer-pointer or the ** thing) causes massive confusion.
second your line pointer does not point to anything this should fix it:
char *line = (char *)malloc(bufsize * sizeof(char));
now line is pointing to valid memory address which we requested via malloc() function.

printf crashes after successful printing

Language is C. I have an array of char* types (char *array[] / char** array) as function argument, and I want to print them all to separate lines like this:
while (*array) {
printf("%s\n", *array);
printf("after last print");
array++;
}
Now for some reason, with a certain input, it manages to print all the values, but immediately crashes after the last *array is printed. So after the last printf, it doesn't print the "after last print" anymore. Unfortunately, I'm on Windows 7 with netbeans C support, without gdb. There were some problems when I tried to install it to netbeans, but that's another story.
First of all, what could be causing this? Secondly, how could I without gdb try to debug this behaviour best? If one provides an answer that helps me to debug the problem and that way solve it, I will grant points from that alone too. Some background information related to the function argument that causes the crash: I used strtok to generate char** arr from char* string, where a space was used as the delimeter.
EDIT:
Some more information: If I inside that same function try to printf the last *array, it works fine, and the program continues normally. So this works:
printf("%s\n", array[4]);
The last index before NULL happens to be 4 in my test case. But then when that same thing is done inside the loop like seen before, it does manage to printf it, but crashes right away after, not printing the second line anymore.
If you don't explicitly initialize the last element of your string array to be null, it's going to be an uninitialized (i.e. wild pointer), so when you dereference it in printf it will crash.
Things to do:
Explicitly initialize the last element of your string array to be NULL so that the loop will actually know to stop at the end.
Instead of incrementing the pointer, increment the offset at which you dereference it with a loop counter variable.
This code works just fine for me and doesn't crash:
#include <stdio.h>
char *array[] = { "Hello", "World", "My", "Name", "Is", "Govind", "Parmar", NULL } ;
int main()
{
int i;
for(i = 0; *(array+i); i++)
{
printf("%s\n", *(array+i));
}
printf("after last print\n");
return 0;
}
I commented out code that comes after the use of this function. This resulted into fully successful run of the code. So apparently, the execution order of the code wasn't linear in a way that it would execute line after line. But after the last *array print it tried to execute code that was coming after the function. Now when I commented out that code, the function works like a charm.
Those who are interested, the code I commented out related to freeing memory from the *arrays.

Program outputting values without initial referencing of Variables(BULLS AND COWS)

So here is the deal , I was writing a Bulls and Cows Game in C and had an interesting observation..It was that my program was outputting values without initial referencing....First look at the whole code
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
int main(){
int i,j,bulls,cows;
//int bulls = 0;
//int cows = 0;
char guess[4];
char chosenword[4] = "onea";
puts("Enter Your best guess <4 letter word>");
gets(guess);
for(i=0;i<4;i++){
if(guess[i] == chosenword[i]){
bulls++;
}
else {
for(j=0;j<4;j++){
if(chosenword[i]==guess[j]){
cows++;
}
}
}
}
printf("Bulls: %d And Cows: %d",bulls,cows);
return 0;
}
As you can see I have not initialized the variables bulls and cows to 0 but still my program outputs
some value or the other eg :
Here as you can see there are three trials..while the value of bulls changes the value of cows remains constant. Can anyone please explain the logic?
Because, other than the initialization, your variable contains some garbage value. You cannot predict what is that value.
In your code, bulls and cows are local variable in [auto]. So, compiler won't be initializing them, unless you do so explicitly in your code.
In contrast to using static or making them global.
Without initialization, using bulls++; or cows++ is creating a scenario read-before-write which may very well lead to undefined behavior. Always initialize your variables.
To avoid the issue: Please uncomment the initialization part in your code. :-)
A word of advice : Please don't use gets(). Use fgets(). Its lot safer.
Next,
char guess[4];
char chosenword[4] = "onea";
change to
char guess[5]; //to hold the terminating null character also
char chosenword[ ] = "onea"; //while initializing, you don't need to specify size explicitly.
EDIT:
In your case, cow is producing constant output because for your inputs, if condition never fails.
You need to avoid using gets() instead use fgets().
Using uninitialized variables leads to undefined behavior.
The value of uninitialized variables is undeterminate. The values you are seeing are some garbage values. So once we say UB anything might happen and explanation for it doesn't make sense.
Please initialize your local variables in order to get right outputs.

gets and puts to get and print a string

i'm trying to get and print a string with gets and puts but i get a segmentation fault error when i use them togheter.
this is the code i'm trying to get this working. [i type the string "prova" to test it]
int main()
{
char *s;
gets(s);
puts(s);
return 0;
}
if i change "gets" with "scanf" i get the same error.
if i change "puts" with "printf("%s", s)" i get the output.
if i declare char *s = "prova" and then puts(s) i get the output.
i also tried to change char *s; with char s[] but i get the same error.
where i'm i wrong on this? ty very much
i know gets is bad, is just bc i'm writing exercise from "C how to program, fifth edition" by Deitel and Deitel
You have multiple problems with that piece of code. To start with gets have been deprecated since the C99 standard, and in the C11 standard it has been removed. The reason is that it's not very safe, and has no bounds-checking and so can write beyond the bounds of the memory you pass to it leading to buffer overflows.
Secondly, you use the uninitialized local variable s. The value of an uninitialized variable is indeterminate, and will be seemingly random. Using an uninitialized local variable leads to undefined behavior, which often leads to crashes.
Another problem is if you initialize s to point to a literal strings. Literals strings are constant (read-only) arrays of characters, and attempting to write to it will again lead to undefined behavior.
You need to allocate some room for the string:
char s[256];
gets(s);
puts(s);
But gets is bad. (It doesn't know how big your buffer is, so what happens if more than 255 characters are read?)
The most important mistake you have is that you are declaring a char pointer, but you are not reserving the space in memory where the characters will be stored, so you got a pointer that point to some random memory adress that you should'nt use. the "right" thing to do will be:
#include <stdio.h>
#include <stdlib.h>
#define LENGHT 20
int main()
{
char *s;
s=malloc(sizeof(char)*LENGHT); //here you make the pointer point to a memory adress that you can use
gets(s);
puts(s);
free (s);
return 0;
}
But also is strongly recommend to avoid using gets because that function doesn't check for the length of the input, so use fgets instead that allow you to do that, you will only need to set the data stream to stdin.
The code will be:
#include <stdio.h>
#include <stdlib.h>
#define LENGHT 20
int main()
{
char *s;
s=malloc(sizeof(char)*LENGHT);
fgets(s,20,stdin);
puts(s);
free(s);
return 0;
}

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