Reputation: 21
My understanding:
char * c means c is pointing nothing.
When I type "Hello World", c is now pointing the first address of "Hello World".
It should print H and e, but I got "Segmentation fault: 11" error.
Can anyone please enlighten me why and how char * c = NULL; is causing an error?
Thanks in advance!
#include <stdio.h>
int main(void)
{
char * c = NULL;
gets(c);
printf("%c, %c\n", c[0], c[1]);
return 0;
}
Upvotes: 1
Views: 757
Reputation: 84541
char *c = NULL;
declares the pointer c
initialized to NULL
. It is a pointer to nowhere.
Recall, A pointer is just a variable that holds the address to something else as its value. Where you normally think of a variable holding an immediate values, such as int a = 5;
, a pointer would simply hold the address where 5
is stored in memory, e.g. int *b = &a;
. Before you can use a pointer to cause data to be stored in memory -- the pointer must hold the address for (e.g. it must point to) the beginning of a valid block of memory that you have access to.
You can either provide that valid block of memory by assigning the address of an array to your pointer (where the pointer points to where the array is stored on the stack), or you can allocate a block of memory (using malloc, calloc
or realloc
) and assign the beginning address for that block to your pointer. (don't forget to free()
what you allocate).
The simplest way is to declare a character array and then assign the address to the first element to your pointer (an array is converted to a pointer to the first element on access, so simply assigning the character array to your pointer is fine). For example with the array buf
providing the storage and the pointer p
holding the address of the first character in buf
, you could do:
#include <stdio.h>
#include <string.h> /* for strcspn & strlen */
#define MAXC 1024 /* if you need a constant, #define one (or more) */
int main (void)
{
char buf[MAXC], /* an array of MAXC chars */
*p = buf; /* a pointer to buf */
if (fgets (p, MAXC, stdin)) { /* read line from stdin */
p[strcspn (p, "\n")] = 0; /* trim \n by overwriting with 0 */
if (strlen (p) > 1) { /* validate at least 2-chars */
printf("%c, %c\n", p[0], p[1]); /* output them */
}
}
return 0;
}
(note: strcspn
above simply returns the number of character in your string up to the '\n'
character allowing you to simply overwrite the '\n'
included by fgets()
with '\0'
-- which is numerically equivalent to 0
)
Example Use/Output
$ ./bin/fgetsmin
Hello
H, e
Look things over and let me know if you have further questions.
Upvotes: 1
Reputation: 155363
gets
doesn't allocate memory. Your pointer is pointing to NULL
, which cannot be written to, so when gets
tries to write the first character there, you seg fault.
The solution is:
char c[1000];
) or a pointer to dynamically allocated memory (char *c = malloc(1000);
), not a NULL
pointer.gets
, which is intrinsically broken/insecure (it can't limit the read to match the size of the available buffer); use fgets
instead.Upvotes: 1