I'm new to C and I'm trying to write a program with a lot of user input. For that purpose I wrote this function:
char * addValue(char * msg){
char * input[80];
printf("%s", msg);
fflush(stdout);
fgets(*input, 80, stdin);
strtok(*input, "\n");
return *input;
}
This function works perfectly in the whole program except in this part:
struct User{
char userid[10];
char email[80];
char name[80];
char password[80];
char downloaded[10];
char registred[10];
};
int change() {
char * query = "SELECT * FROM Users WHERE user_id=";
char * userid = addValue("Enter the User ID: "); // Works here
// Here is a MySQL query
char * email = addValue("Mail: "); // -> Segmentation Fault
printf("%s\n", email);
struct User usrvalues;
strcpy(usrvalues.email, email);
return 0;
}
I have absolutely no idea, why the second function call is not working. I have other functions in the program where I call the addValue() function multiple times without any errors.
When I debug this with gdb, I get this result:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6445b77 in __GI__IO_getline_info () from /usr/lib/libc.so.6
bt
gives me the following informations:
#0 0x00007ffff6445b77 in __GI__IO_getline_info () from /usr/lib/libc.so.6
#1 0x00007ffff6444a3d in fgets () from /usr/lib/libc.so.6
#2 0x000000000040142b in addValue ()
#3 0x00000000004016e9 in change ()
#4 0x0000000000401bd0 in main ()
I tried different inputs ("" (an empty string), different numbers like 100 and different strings like "test"), but it every time it ends with a segmentation fault.
What am I doing wrong?
input
is an uninitialized array of pointers. By doing *input
you get the first uninitialized pointer and pass it to fgets
.
I'm sure you didn't mean to create an array of pointers to char
, but an array of char
:
char input[80];
However, you have a more serious problem than that, because you then return a pointer to this local array input
(well, after the change described above you would), and that leads to undefined behavior because local variables are local, they disappear when the function returns and will leave you with a stray pointer.
You have two solutions to this problem: The first is to declare the array in the calling function, and pass it (and its size) to the function, just like you pass input
and its length to fgets
now.
The second solution is to create the array dynamically using malloc
, and then remember to free
it once you're done with it.