Storing a string in char pointer (using scanf) - c

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char *s1;
char *s2;
printf("Enter the string : ");
scanf("%s",s1);
printf("Enter the string : ");
scanf("%s",s2);
return 0;
}
I'm facing problems in taking inputs in char pointer. Here I'm just taking 1 word as input but Scanf isn't taking any inputs at all when using char pointer, but works well with char arrays. Is it a code blocks bug?

A pointer is a variable that holds a memory address.
An uninitialized variable contains (generally) some random garbage number.
When you pass some random garbage number to scanf and tell it to store a string at that address, it's no surprise that (usually) the program crashes.
It makes no sense to tell scanf to store a string at an address where you don't know what the address is. It's like telling your friend to come over to your house and when they ask which house is yours, you click somewhere random on Google Maps. It's probably going to be in the middle of the ocean or something and they'll drown.
What you need to do is make a space to put the string (such as by declaring an array) and then tell scanf to put the string in that space that you specifically made to hold the string.
A pointer to a string does not hold the string. A pointer to a string is just a signpost saying "the string is over there --->", and you can change it if you want it to point to a different place, maybe holding a different string, but it's never going to hold a string itself.

This is a beginner-C-programmers' bug as old as the language itself.
There are two good solutions to your problem, either change the definitions of s1 and s2 to something like
char s1[BUFFER_LENGTH];
char s2[BUFFER_LENGTH];
...where BUFFER_LENGTH-1 is some sufficiently long string length, to tell the compiler to allocate enough memory on the stack, or manually allocate memory in the heap for them using malloc() like so:
char *s1 = malloc(BUFFER_LENGTH);
char *s2 = malloc(BUFFER_LENGTH);
But keep in mind that in both cases your code is unsafe because for any finite-length buffer, there is a string too long for it, which can cause your program to crash or overwrite something important in memory or give hackers access to stuff etc. etc.
A safe solution is to allocate memory for your strings in one of the two above ways, and only read strings that are small enough to fit into them. If you require the program to be able to handle a string of any length, your code will be much more complex, but there's still a safe way to do it.
#include <stdio.h>
#define BUFFER_LENGTH 20 //Arbitrary max string length + 1
int main(){
char s1[BUFFER_LENGTH]; //Can safely hold 19 chars for string and a null terminator
char s2[BUFFER_LENGTH];
printf("Enter the string : ");
scanf("%19s",s1); //%19s tells the function to only read max 19 characters
printf("Enter the string : ");
scanf("%19s",s2);
{
In the above example a string longer than 19 characters will be truncated, for instance "012345678901234567890" will be stored in s1 as "0123456789012345678" and s2 will have "90" since scanf will just use the leftover characters in the input buffer for the next call.

Related

I have problem in string, in using the gets function, in c language

I have a problem with string in the c language
we know, the string is known as a null-terminated character** array, in the string, we declare how many characters this string is store. and the memory of the character is 1byte. when we declare char name[5]; it means the string store at least 4 characters value and null value.
but there is a problem withstrong text the gets function it.
when we have entered a name that contains more than 5 characters it is accepted and prints all characters. In this case, the compiler does not throw the warning.
Please tell me the solution to it.......
the code is below.
#include<stdio.h>
int main()
{
char name[4]="smti prajapati";
printf("Print the name througth the initilizing : ");
puts(name);
printf("Enter the name : ");
gets(name);
printf("Print the name througth the user : ");
puts(name);
return 0;
}
In the terminal program trow the look like this error
rough.c: In function 'main':
rough.c:5:18: ***warning: initializer-string for array of chars is too long***
char name[1]="smti prajapati";
^~~~~~~~~~~~~~~~
Print the name througth the initilizing : s3
Enter the name : smit prajapati
Print the name througth the user : smit prajapati
You’ve declared the name array to have a single element; it’s not large enough to hold the contents of the string "smti prajapati". You’d need to declare name to be at least 15 elements wide - 14 characters in the string plus the zero terminator.
You can omit the size in the declaration and write
char name[] = "smti prajapati";
and the array size will be taken from the size of the initializer.
Note that the size of name is fixed after it is defined, and will not able to store strings longer than the initializer.
Do not use gets; if you enter a string that’s too long for the array, it will write those extra characters to whatever follows the array. This is known as a buffer overflow, and can lead to anything from corrupted data, a runtime error, or branching to a random location in your program. Buffer overflows are a common malware exploit. Use fgets instead, as it allows you to limit how many characters get written to the target.
The declaration and assignment:
char name[1] = "smti prajapati";
Can never work because you assign a string with 14 characters plus the null byte to a char array that only has space for 1 character.
The reason why you don't get errors or warnings with some ill-formed code can be explained by leeway given by C to the programmer, compilers are not mandated to issue warnings due to some types of ill-formed code like your own, this falls in the category of undefined behavior, and it's up to the programmer to avoid it.
You could use:
char name[] = "smti prajapati";
This way the size of the array will be deduced when initialized.
Or if you want to explicitly use a size:
char name[15] = "smti prajapati";
Note that I added an extra space for the null byte, it is mandatory if you want to handle name as a propper string. Also note that once the char array is given a size, it will not change, so when you store other strings in name keep that in mind.
The other problem is gets, you should never use it, it's a very dangerous function, it does not check the bounds of the destination buffer and therefore can easily cause a buffer overflow and that can cause all kinds of trouble. Recent compilers don't even support it anymore as it was deprecated and later removed from the C standard.
Even those which do still support it often issue warnings similar to:
warning: the `gets' function is dangerous and should not be used.
Here are two examples of the output of two modern compilers when you use it.
Summarizing and concluding, use fgets instead:
fgets(name, sizeof name, stdin);
When you use arrays in C you are using a fixed memory space. If I want to save "Hello World!" in memory, I have to reserve an array of length 13. In C it looks as:
char aString[13] = "Hello World!"
It may go as high as 20, but no lower than 13. Why? Strings have characters that we care and the last one is the null character (its value is 0). So, you need to reserve thirteen characters.
In your code you are reserving only 1 byte (1 character). At least, you have to reserve 15 bytes.
Try this code:
#include<stdio.h>
int main()
{
char name[15]="smti prajapati";
printf("Print the name througth the initilizing : ");
puts(name);
printf("Enter the name : ");
gets(name);
printf("Print the name througth the user : ");
puts(name);
return 0;
}
I compiled the code without problems. Also, you are able to not specify the length and It is going to work right. The best solution is dynamic memory. Avoid gets(). It has security issues. Instead, use fgets().
You have a number of misunderstandings. Let's look at them in order.
in the c language we know, the string is known as a null-terminated character** array
In C, a string is a null-terminated array of char. It is very common to refer to a string using a character pointer, char *. It may have been a typo when you said "character**", but type char ** is a pointer-to-pointer, which is something else.
when we declare char name[5]; it means the string store at least 4 characters value and null value.
Correct.
char name[1]="smti prajapati";
This is incorrect. Your compiler correctly warned you: warning: initializer-string for array of chars is too long
when we have entered a name that contains more than 5 characters it is accepted and prints all characters.
Right. Sometimes, when you break the rules, you get away with it.
In this case, the compiler does not throw the warning.
Right. C does not always detect or complain about buffer overflow. In general, it is your responsibility to make sure your arrays are allocated large enough for the strings you try to store in them.

What's the difference between a string and a user entered string in C

I'm using with a smaller piece of code to test functionality for a larger (beginner) program, but I don't understand the difference between two strings.
I found and used:
#include <stdio.h>
#include <string.h>
int main()
{
char *string, *found;
string = strdup ("1/2/3");
printf("Orig: '%s'\n",string);
while ((found = strsep(&string,"/")) != NULL )
printf ("%s\n",found);
return (0);
}
and this print the tokens one at a time.
Then when I try and move to a user entered string:
#include <stdio.h>
#include <string.h>
int main()
{
char string[13],
char *found, *cp = string;
fprintf(stderr, "\nEnter string: ");
scanf("%12s",string);
printf("Original string: '%s'\n",string);
while((found = strsep(&cp,"/,-")) != NULL )
printf("%s\n",found);
return(0);
}
I get a seg fault. I understand the basics of pointers, arrays and strings, but clearly I'm missing something, and would love for someone to tell me what it is!
Also - if I change printf("%s\n",found); to printf("%i\n",found); I get some junk integers returned, but always the correct amount, e.g. If I enter 1/2/3 I get three lines of integers, 1111/2222 I get two lines.
Thanks!
-Edit-
There was an adittional problem with strsep, detailed here. Thanks all.
In the first piece of code, string is assigned the return value of strdup, which allocates space for the string to duplicate and returns a pointer to that allocated space.
In the second piece of code, string uninitialized when it is passed to scanf, so scanf is reading the invalid value in that pointer and attempting to dereference it. This invokes undefined behavior which in this case manifests as a crash.
You need to set aside space for the user's string. A simple way to do this is to create an array of a given size:
char string[80];
Then tell scanf how many characters it can read in:
scanf("%79s",string);
Differences between the two cases:
In the first case string points to valid memory that was allocated by strdup while in the second case you are trying to read into invalid memory.
The first case is well behaved while the second case is cause for undefined behavior.
The second case can be fixed by allocating memory for it using malloc or using a fixed size array.
char *string,*found;
string = malloc(100); // Make it large enough for your need.
fprintf(stderr, "\nEnter string: ");
scanf("%99s",string);
or
char string[100], *found;
fprintf(stderr, "\nEnter string: ");
scanf("%99s",string);
Make sure you deallocate dynamically allocated memory. Otherwise, your program leaks memory.
You should allocate memory for the user input string.
First option is statically
char string[256];
and second option is dynamically using malloc() function
char *string;
string = (char*) malloc(256 * sizeof(char));
if (string == NULL)
{
//error
}
Don't forget at the end to release the allocated memory
free(string);
In user enter string case you do not have memory allocated to the pointer string.In the first case, strdup is allocating memory for string pointer while in the second case you do not have any memory associated with string pointer leading to segfault. first, allocate memory using malloc and then use scanf.
You didn't allocate the space needed !
You have to have a memory space to write to.
You can have it statically "char string[256]", or dynamically with allocation.
In your first example, you use "strdup" that does a malloc, but scanf will not allocate memory for you.
If you want all the user input, you usually wrap the scanf in a while loop in order to retrieve the user input chunk by chunk. Then you have to reallocate each time your buffer is insuffisante to add the chunk.
If you just want to retrieve a string from stdin without doing any format-checking, I strongly recommand fgets.
char string[13]
char cp=string
Here cp is a variable of type char and as 1 byte of memory allocated
It won't be able to store a char array of 13 character which would be 13 bytes, and it's because of this you are getting segmentation fault
The reason is very simple. Your string variable is a char pointer and you need to allocate memory to it to store a string.Probably in your first case strdup ("1/2/3"); returns a string and your char pointer *string points to the string return by strdup function and that is the reason why you are not getting the segmentation error in the first case. Even in your first case also you might get a segmentation error if enter a very long string.
so allocate enough memory to the string pointer like below in your second example and that will fix your problem:-
char *string = malloc(50);// here malloc will allocate 50 bytes from heap

scanf() works despite 0-length buffer and compiler warning. What is going on?

My compiler (clang) shows this message:
11:17:warning: format specifies type 'char *' but the argument has
type 'char (*)[0]' [-Wformat]
scanf("%s", &name);
~~ ^~~~~
1 warning generated.
from the following code (greetings program):
/*
* Program: gretting2.c
* Utility: Display a greeting with your name.
* Author: Adrián Garro.
*/
#include <stdio.h>
int main () {
char name[0];
printf("-------------------\n");
printf("Write your name: \n");
printf("-------------------\n");
scanf("%s", &name);
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
}
What is actually going on, and how can I fix it?
In order to understand this, you have to understand what scanf is doing. scanf in this case is reading a string from stdin, and placing it into a buffer that you give it. It does not allocate that space for you, or detect overflow. You need to allocate sufficient space for your string. As it stands now, you are allocating zero space for your string, so everything is an overflow. This is a major bug.
Say instead of char[0], you did char[40], as another user suggests.What if the user of your program writes more than 40 characters? This results in undefined behavior. Essentially, it will write to memory you don't want it to write to. It might cause a segfault, it might result in crucial memory getting overwritten, or it might happen to work. This is a weakness of scanf. Look into fgets. You tell it the size of your buffer, and input will be truncated to fit.
Of course, that has nothing to do with your warning. You're getting a warning because referring to the name of an array is the same as referring to a pointer to its first element, i.e. name <==> &(name[0]). Taking a pointer to this is like taking a pointer to a pointer, i.e. &name <==> &&(name[0]). Since scanf is looking for an argument of type char*, and it's getting a pointer to that, the type checker complains.
Your code exhibits "undefined behavior." This means anything could happen. Anything.
You are passing a zero-length array to scanf(). Also, you are not passing the array length in the format string. This results in a buffer overflow vulnerability (always, in the case of a zero-length target array).
You need something like this:
char name[51];
scanf("%50s", name);
Note the %50s now specifies the size of the target array (less one, to leave room for the null terminator!), which avoids buffer overflow. You still need to check the return value of scanf(), and whether the input name is actually too long (you wouldn't want to truncate the user's input without telling them).
If you're on Linux, check out the tool called valgrind. It is a runtime memory error detector (among other things), and can sometimes catch errors like this for you (and much less obvious ones, which is the main point). It's indispensable for many C programmers.
Just change this:
scanf("%s", &name);
to:
scanf("%39s", name);
and this:
char name[0];
to:
char name[40];
Also to you have to end it with a '\0' with:
name[39] = '\0';
Depending on how robust you want this to be you will want to reconsider the approach. I guess the first thing is whether you understand the type you are using when declaring char name[ 0 ]. this is a 'zero-sized' array of byte-sized characters. This is a confusing thing and it wouldn't surprise me if its behaviour differs across compilers...
The actual warning being complained by the compiler is that the type doesn't match. If you take the address of the first character in the array you can get rid of that (i.e. use &( name[ 0 ] ) in the scanf call). The address of name is its location on the stack - it just so happens that the array implementation uses that same location to store the array data, and name is treated differently by the compiler when used on its own so that the address of an array is the same as the address of its first element...
Using char name[ 0 ] leaves you open to causing memory corruption because there is nowhere for the string to be read, and implementation details may just luck out and allow this to work. One simple way to fix this is to replace 0 with a meaningful number which you take to the maximum length of the input string. Say 32 so that you have char name[ 32 ] instead... however this doesn't handle the case of an even longer string.
Since we live in a world of lots of memory and large stacks you can probably do char name[ 4096 ] and use 4KB of memory for the buffer and that will be absolutely fine for real world usage.
Now... if you want to be a little anal and handle pathological cases, like a user leaning on some keys whilst asleep for hours before pressing enter and adding some enormous 8000 character long string there are a few ways to handle that too with 'dynamic memory allocation', but that might be a bit beyond the scope of this answer.
As an aside, from what I understand char foo[ 0 ] is intentionally valid - it may have originated as a hack and has a confusing type, but is not uncommonly relied on for an old trick to create variable sized structs as described in this page from the GCC online docs
char name[0]; ---> char name[100];
/* You need to allocate some memory to store the name */
2.scanf("%s", &name);----> scanf("%s", name);
/* scanf takes char* as an argument so you need to pass string name only. */
i don't think that scanf("%(length - 1)s", name); is needed.
Because %s is used to reads a string. This will stop on the first whitespace character reached, or at the specified field width (e.g. "%39s"), whichever comes first.
except these don't tend to be used as often. You, of course, may use them as often as you wish!
/
*
* Program: gretting2.c
* Utility: Display a greeting with your name.
* Author: Adrián Garro.
*/
#include <stdio.h>
int main () {
char name[100];
printf("-------------------\n");
printf("Write your name: \n");
printf("-------------------\n");
scanf("%s", name);
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
}
Because the correct way is
scanf("%s", name);
/* ^ no ampersand
and what is
char name[0];
you should specify a non-zero length and use it for scanf length specifier
scanf("%(length - 1)s", name);
/* ^ sunstitite with the value */
there were several problems with the OPs posted code
the following fixes most of them
I includd comments to indicate where the problems are
int main ()
{
//char name[0]; // this did not allow any room for the name
char name[100] = {'\0'}; // declare a 100 byte buffer and init to all '\0'
printf("-------------------\n");
printf("Write your name:, max 99 char \n"); // 99 allows room for nul termination byte
printf("-------------------\n");
//scanf("%s", &name); // this has no limit on length of input string so can overrun buffer
if( 1 == scanf("%99s", name) ) // 1) always check returned value from I/O functions
// 2) no '&' before 'name' because
// arrays degrade to pointer to array when variable
// name is used
// 3) placed max size limit on format conversion string
// so input buffer 'name' cannot be overflowed
{ // then scanf failed
perror( "scanf failed for name" );
return(-1); // indicate error
}
// implied else, scanf successful
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
return(0); // indicate success
} // end function: main
You are reading a "string", thus the correct way is:
scanf("%s", name);
Why does the compiler complain? When you provide an argument in scanf, you provide the memory location of the variable. For example:
int x;
scanf("%d", &x);
&x is int *, i.e., a pointer to an integer, so x will get the correct value.
When you read a string, you're actually reading many char variables together. To store them, you need a char * array; well, name is char * on its own, so no need to write &name. The latter is char **, i.e., a 2-dimensional array of char.
By the way, you also need to allocate space for the characters to read. Thus, you have to write char name[20] (or any other number). You also need to provide a return 0; in your int main().

The compiler shows a warning from this code [duplicate]

My compiler (clang) shows this message:
11:17:warning: format specifies type 'char *' but the argument has
type 'char (*)[0]' [-Wformat]
scanf("%s", &name);
~~ ^~~~~
1 warning generated.
from the following code (greetings program):
/*
* Program: gretting2.c
* Utility: Display a greeting with your name.
* Author: Adrián Garro.
*/
#include <stdio.h>
int main () {
char name[0];
printf("-------------------\n");
printf("Write your name: \n");
printf("-------------------\n");
scanf("%s", &name);
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
}
What is actually going on, and how can I fix it?
In order to understand this, you have to understand what scanf is doing. scanf in this case is reading a string from stdin, and placing it into a buffer that you give it. It does not allocate that space for you, or detect overflow. You need to allocate sufficient space for your string. As it stands now, you are allocating zero space for your string, so everything is an overflow. This is a major bug.
Say instead of char[0], you did char[40], as another user suggests.What if the user of your program writes more than 40 characters? This results in undefined behavior. Essentially, it will write to memory you don't want it to write to. It might cause a segfault, it might result in crucial memory getting overwritten, or it might happen to work. This is a weakness of scanf. Look into fgets. You tell it the size of your buffer, and input will be truncated to fit.
Of course, that has nothing to do with your warning. You're getting a warning because referring to the name of an array is the same as referring to a pointer to its first element, i.e. name <==> &(name[0]). Taking a pointer to this is like taking a pointer to a pointer, i.e. &name <==> &&(name[0]). Since scanf is looking for an argument of type char*, and it's getting a pointer to that, the type checker complains.
Your code exhibits "undefined behavior." This means anything could happen. Anything.
You are passing a zero-length array to scanf(). Also, you are not passing the array length in the format string. This results in a buffer overflow vulnerability (always, in the case of a zero-length target array).
You need something like this:
char name[51];
scanf("%50s", name);
Note the %50s now specifies the size of the target array (less one, to leave room for the null terminator!), which avoids buffer overflow. You still need to check the return value of scanf(), and whether the input name is actually too long (you wouldn't want to truncate the user's input without telling them).
If you're on Linux, check out the tool called valgrind. It is a runtime memory error detector (among other things), and can sometimes catch errors like this for you (and much less obvious ones, which is the main point). It's indispensable for many C programmers.
Just change this:
scanf("%s", &name);
to:
scanf("%39s", name);
and this:
char name[0];
to:
char name[40];
Also to you have to end it with a '\0' with:
name[39] = '\0';
Depending on how robust you want this to be you will want to reconsider the approach. I guess the first thing is whether you understand the type you are using when declaring char name[ 0 ]. this is a 'zero-sized' array of byte-sized characters. This is a confusing thing and it wouldn't surprise me if its behaviour differs across compilers...
The actual warning being complained by the compiler is that the type doesn't match. If you take the address of the first character in the array you can get rid of that (i.e. use &( name[ 0 ] ) in the scanf call). The address of name is its location on the stack - it just so happens that the array implementation uses that same location to store the array data, and name is treated differently by the compiler when used on its own so that the address of an array is the same as the address of its first element...
Using char name[ 0 ] leaves you open to causing memory corruption because there is nowhere for the string to be read, and implementation details may just luck out and allow this to work. One simple way to fix this is to replace 0 with a meaningful number which you take to the maximum length of the input string. Say 32 so that you have char name[ 32 ] instead... however this doesn't handle the case of an even longer string.
Since we live in a world of lots of memory and large stacks you can probably do char name[ 4096 ] and use 4KB of memory for the buffer and that will be absolutely fine for real world usage.
Now... if you want to be a little anal and handle pathological cases, like a user leaning on some keys whilst asleep for hours before pressing enter and adding some enormous 8000 character long string there are a few ways to handle that too with 'dynamic memory allocation', but that might be a bit beyond the scope of this answer.
As an aside, from what I understand char foo[ 0 ] is intentionally valid - it may have originated as a hack and has a confusing type, but is not uncommonly relied on for an old trick to create variable sized structs as described in this page from the GCC online docs
char name[0]; ---> char name[100];
/* You need to allocate some memory to store the name */
2.scanf("%s", &name);----> scanf("%s", name);
/* scanf takes char* as an argument so you need to pass string name only. */
i don't think that scanf("%(length - 1)s", name); is needed.
Because %s is used to reads a string. This will stop on the first whitespace character reached, or at the specified field width (e.g. "%39s"), whichever comes first.
except these don't tend to be used as often. You, of course, may use them as often as you wish!
/
*
* Program: gretting2.c
* Utility: Display a greeting with your name.
* Author: Adrián Garro.
*/
#include <stdio.h>
int main () {
char name[100];
printf("-------------------\n");
printf("Write your name: \n");
printf("-------------------\n");
scanf("%s", name);
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
}
Because the correct way is
scanf("%s", name);
/* ^ no ampersand
and what is
char name[0];
you should specify a non-zero length and use it for scanf length specifier
scanf("%(length - 1)s", name);
/* ^ sunstitite with the value */
there were several problems with the OPs posted code
the following fixes most of them
I includd comments to indicate where the problems are
int main ()
{
//char name[0]; // this did not allow any room for the name
char name[100] = {'\0'}; // declare a 100 byte buffer and init to all '\0'
printf("-------------------\n");
printf("Write your name:, max 99 char \n"); // 99 allows room for nul termination byte
printf("-------------------\n");
//scanf("%s", &name); // this has no limit on length of input string so can overrun buffer
if( 1 == scanf("%99s", name) ) // 1) always check returned value from I/O functions
// 2) no '&' before 'name' because
// arrays degrade to pointer to array when variable
// name is used
// 3) placed max size limit on format conversion string
// so input buffer 'name' cannot be overflowed
{ // then scanf failed
perror( "scanf failed for name" );
return(-1); // indicate error
}
// implied else, scanf successful
printf("------------------------------------\n");
printf("Hello %s, nice to meet you\n",name);
printf("------------------------------------\n");
return(0); // indicate success
} // end function: main
You are reading a "string", thus the correct way is:
scanf("%s", name);
Why does the compiler complain? When you provide an argument in scanf, you provide the memory location of the variable. For example:
int x;
scanf("%d", &x);
&x is int *, i.e., a pointer to an integer, so x will get the correct value.
When you read a string, you're actually reading many char variables together. To store them, you need a char * array; well, name is char * on its own, so no need to write &name. The latter is char **, i.e., a 2-dimensional array of char.
By the way, you also need to allocate space for the characters to read. Thus, you have to write char name[20] (or any other number). You also need to provide a return 0; in your int main().

need help about string in c program [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Segmentation Fault - C
#include<stdio.h>
#include<string.h>
int main()
{
char *p;
printf("enter some thing:");
gets(p);
printf("you have typed:%s\n",p);
}
Why doesn't this program work?
i can't use pointer as a string.
Output is:
enter some thing:raihan
Segmentation fault (core dumped)
I get this error every time when I use a char pointer.
How can I solve this problem?
I am using code-blocks on Linux mint13 KDE.
You have not allocated memory. You just declared a pointer, p, but didn't make it point at anything. That explains the segmentation fault. You will need to allocate memory for your buffer.
What's more, gets does not allow you to specify how big the buffer is. So you are at risk of running over the end of the buffer. So use fgets instead.
int main(void)
{
char buffer[1024];//allocates a buffer to receive the input
printf("enter some thing: ");
fgets(buffer, sizeof(buffer), stdin);
printf("you have typed: %s\n", buffer);
return 0;
}
I also corrected your declaration of main and made sure that it returns a value.
You haven't allocated any memory for p. Also, use fgets instead of gets which may overflow the input buffer.
char *p;
printf("enter some thing:");
gets(p);
Wrong. Gets() tries to fill in the array pointed to by the supplied pointer - and it segfaults, because that pointer hasn't been initialized, so it might (and does) point to some garbage/invalid memory location. Use
char p[256];
or something like this instead - you still have to worry about a buffer overflow in if the user enters a string longer than 255 characters. You can solve that one using
fgets(p, sizeof(p), stdin);
Your pointer is declared but you have not initialised it and so its value will be some arbitrary memory location that you may not have access to write to. Thus anytime you read or write to this you run the risk of segfault. Allocate some heap memory for the pointer using a call to malloc then you wont get segfaults when writing to it.
You have just defined a pointer - no memory for the characters have been allocated!
Use either an array or malloc.
A pointer is just a memory address. It says "you have some data here". But it doesn't actually reserve that data.
In your case the problem was two-fold. The pointer didn't point to valid memory and you never even set it to anything (so it pointed to somewhere random).
You can fix this in different ways. The easiest is to just use an array (it's sort of implicitly a pointer):
char something[100];
printf("enter some thing:");
gets(something);
That gives you 100 chars on the stack. You can also point to it if you want, but in this case it's a bit redundant:
char *p = something;
The other way is dynamic allocation, where you ask the operating system at runtime to give you some number of bytes. This way you have to give it back when you're finished using it.
char *something = (char*)malloc( 100 * sizeof(char) ); // Ask for 100 chars
printf("enter some thing:");
gets(something);
free(something); // Do this when you don't need that memory anymore.
PS: Remember when you have strings, you always need one extra byte than the number of characters you intend to store. That byte is for the string terminator, and the value of it is 0.

Resources