Segmentation fault: 11 in basic single source C program - c

I am an absolute beginner is C, so bear with me.
I am getting a segmentation fault: 11 directly after I put my Name in When I run my code. When I compile it never has any errors so I am really not sure what I am doing wrong. I am on mac also if that affects anything.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char * name;
char * pass;
} user;
void prompt(user u) {
char passw;
char name;
printf("Enter your name:\n");
scanf("%s", &name);
if (strncmp(u.name, &name, strlen(u.name)) == 1) {
printf("Correct! Please input password:\n");
scanf("%s", &passw);
if (strncmp(u.pass, &passw, strlen(u.pass)) == 0) {
printf("Congrats! you got in.\n");
}
}
}
int main() {
user me;
me.name = "Me";
me.pass = "1234";
prompt(me);
return 0;
}

The problem here is with the variable type name and the corresponding format specifier. You defined it to be a char, but you use %s to scan the value. It causes a bound-overflow that creates undefined behavior.
You need to make name an array, like
char name[64] = {0}; //size is for demo
and the, use scanf() like
scanf("%63s", name);
same goes for passw, also.
FWIW, %s is used to scan a string, whereas, to intake a single char, you need to use %c format specifier.
Also, you can consider having a look at the man page for fgets() as this is considered a safer alternative.

Related

Segmentation fault (core dumped) in programme in c?

I'm a student and I m learning c (programming in ANSI c -> fifth edition) and facing the below error:
I'm implementing one program with typedef
In below c program give an error:
main.c:8:6: warning: ‘gets’ is deprecated [-Wdeprecated-declarations]
/usr/include/stdio.h:638:14: note: declared here
main.c:(.text+0x1f): warning: the `gets' function is dangerous and should not be used.
enter name:cara
Segmentation fault (core dumped)
program:
#include <stdio.h>
char * read(void); //here I m writing prototype but I don't know what is the prototype and why here write the prototype?
char * read(void)
{
char * name;
printf("enter name:");
gets(name); //get string input using gets(..) function
return name;
}
void main()
{
char * name;
name = read();
printf("welcome,%s\n",name);
}
above program is a complexity that is why I m using typedef in the below program:
this below program continuously run why?
#include <stdio.h>
typedef char * string;
string read(void);
string read(void)
{
string name;
printf("enter name:");
gets(name);
return name;
}
void main()
{
string name;
name = read();
printf("welcome,%s\n",name);
}
What I'm doing wrong?
There are a couple of things wrong with this. When you do char * name, you define name as a char pointer, but you don't actually allocate any space for the string to be stored. Hence, when you try to write values into that string, you're writing values in a random place that may not be writable or may contain crucial data that cannot be overwritten. Instead, try declaring name as char name[256]; to allocate enough space for it. Also, don't use gets, as it can lead to very, very, nasty things. Instead, use fgets to read input, and provide an upper limit on the number of characters equal to the amount of data you allocated. So, if you declared name as char name[256];, call fgets with fgets(name, 256, stdin);
The program has undefined behavior because you are using an uninitialized pointer that has an indeterminate value
char * name;
printf("enter name:");
gets(name);
You need to allocate memory where you are going to read a string.
As for the function gets then it is indeed an unsafe function and is not supported by the C Standard anymore. Use instead the standard C function fgets.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
And using a typedef like this
typedef char * string;
is a bad idea. For example using this typedef name you are unable to declare a pointer to constant data like
const char *p;
because this declaration
const string p;
is not equivalent to the above declaration but means the following declaration
char * const p;
The program can look for example the following way
#include <stdio.h>
char * read( char *s, size_t n )
{
s[0] = '\0';
printf( "Enter name: " );
fgets( s, n, stdin );
return s;
}
int main( void )
{
enum { N = 100 };
char name[N];
printf( "%s", read( name, N ) );
}
Its output might look like
Enter name: rahul_
rahul_
Pay attention to that the function fgets can append the entered string with the new line character '\n'. To remove it you can use the following trick
#include <string.h>
//...
name[ strcspn( name, "\n" ) ] = '\0';

Is this a misunderstanding of the functionality of strcpy()?

#include <stdio.h>
#include <string.h>
int main(void) {
int number_of_members;
char family[number_of_members][20][number_of_members][20];
char member_name[20];
char birth_state[20];
char family_last_name[20];
printf("What is the last name of the family?\n");
scanf("%s", &family_last_name);
printf("How many members do you want to create?\n");
scanf("%d", &number_of_members);
int const FAMILY_SIZE = number_of_members;
number_of_members = number_of_members -1;
printf("Enter the family member name: \n");
for(number_of_members;number_of_members>-1;number_of_members--)
{
scanf("%s", &member_name);
strcpy(family[number_of_members], member_name);
printf(" %d %s %s\n",number_of_members, member_name, family_last_name);
}
printf("%s, %s ", family[0], family[1]);
return 0;
}
Here is the output:(from Ideone.com)
Ideone.com with code
The input to this code is: Layne , 2 , tim , jim.
When run, it shows the correct index with the name in the array however, once out it will show the last entered name, jim, as family1 and family[0]. Am I not understanding how strcpy() works? or is it a logic error?Some assistance soon would be appreciated!
This is very very wrong
int number_of_members;
char family[number_of_members][20][number_of_members][20];
Because you haven't initialized number_of_members.
Because it doesn't make sense whatsoever, it's not possible that you really need this kind of array.
And yes, if you enable compiler warnings it will hit you in your nose with a stick, because
strcpy(family[number_of_members], member_name);
shouldn't even compile and is undefined behavior since the type of family[number_of_members], is an array of arrays of arrays of char.
strcpy can take an array of char's because it will be automatically converted to a char poitner, and provided that the contents of the array comply with what a c string is, then strcpy() will work correctly, in your case the behavior is undefined because almost surely the '\0' will never be found in the destination pointer.
instead of
int num_of_members;
char family[number_of_members][20][number_of_members][20];
which is not C code, do this
#define MAX_MEMBERS 20
char family[MAX_MEMBERS][20];
which creates a rectangular array of arrays each of 20 bytes long

I can't seem to print out a string from a structure but I can print an integer

My code is suppose to get the names of students and the student grade. After that I try to print the student names from the structure that I made and I can only get the grade to print. I get an error when trying to print the string using
printf("%s", test[0].names);
and the error says,
Unhandled exception at 0x0fe113af (msvcr100d.dll) in StudentNamesAndGrades.exe: 0xC0000005: Access violation reading location 0x65736f4a.
But when I use
printf("%d", test[0].studentScores);
It prints out the score of the first student. Here is the entire code because it might be something other than the way I'm trying to print it out.
#include <stdio.h>
#include <string>
/*
this program will get a name of students
and then you will enter the grade for each one :)
*/
struct students
{
char *names;
int studentScores;
};
int main(void)
{
int numStudents = 0;
students *test;
int i;
printf("Enter the number of students in your class: ");
scanf("%d", &numStudents);
test = (students*)malloc(numStudents * sizeof(students));
printf("Enter the names of the %d students\n", numStudents);
for (i = 0; i < numStudents; i++)
{
printf("Enter the name of student %d: ", i + 1);
scanf("%s", &test[i].names);
printf("Enter the students score: ");
scanf("%d", &test[i].studentScores);
}
printf("%d", test[0].studentScores);
printf("%s", test[0].names); // This is where I get a problem :/
return 0;
}
You did not allocate memory for char *names; while taking input at all.
Your struct could be like:
typedef struct students
{
char names[30];
int studentScores;
}students;
Also using fgets is safer than using scanf.
You need to allocate space for the names field, but I would recommend a different approach
struct students
{
char names[100];
int studentScores;
};
and then change the scanf() to
scanf("%99s", test[i].names);
there is another mistake in your first scanf() your are passing the address to the pointer, instead of the pointer.
You should use the address of & operator for the integer, because you need to pass a pointer to an integer for the "%d" specifier, but your names field variable was already a pointer, so no neet to take it's address.
Some other tips you might be interested in
Don't cast the result of malloc, although it seems that you are erroneously using a c++ compiler to compile c code, and in c++ you do need the cast, in c you don't, it makes your code harder to read and other problems which you can read with the most popular c question on Stack Overflow.
Check the return value from malloc, it doesn't matter how unlikely it could fail, since it could theoretically fail, you must check it's return value, which is NULL on failure.

Name will not display

I have my code compiling without issue, accepting input without issue, printing without issue. HOWEVER, it does not want to print the name it only prints a space. It was working and I made some additional changes and I don't know what went wrong. Any thoughts would be greatly appreciated!
#include <stdio.h>
#include <stdlib.h>
struct File {
char type;
char name;
int time;
int size;
}f;
int main()
{
struct File * c = malloc(1 *sizeof(struct File));
printf("Enter file name: \n");
scanf("%s", &f.name);
printf("Enter the file size: \n", f.size);
scanf(" %d", &f.size);
printf("Enter when the file was last accessed: \n", f.time);
scanf(" %d", &f.time);
printf("Enter the file type: \n", f.type);
scanf("%s", &f.type);
printf("\n");
structPrint();
}
structPrint()
{
printf("Filename: %s, File Size: %d, Type: [%s], Access Time: %d \n", &f.name, f.size, &f.type, f.time);
}
Your structure contains space for exactly 1 character type and 1 character name. Both of those are likely to be longer than a single character - in fact, they must, since they're presumably supposed to be null-terminated strings. Try making those into arrays instead...
Your problem is that you are storing name and type as chars, not char[]s. You can either allocate memory for them at runtime or declare them as arrays of fixed size. My code will use the latter.
Change the struct to something like this:
struct File {
char type[12]; /*or whatever maximum sizes you think are appropriate */
char name[64];
int time;
int size;
}f;
Remove the & operators in the scanf and printf calls for name and type.

strncmp/strcpy corrupting source

today i was trying to get friendly with char * string... but it seems im failing :)
Every time i call strcmp/strncmp/strcpy function my source gets corrupted...
here is the snippet
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student
{
int UID;
char name[20];
char surname[20];
};
char * getString(int minChars, int maxChars);
struct student * myStud;
int main(int argc, char** argv) {
myStud = (struct student*)malloc(sizeof(struct student));
while(1)
{
printf("\nEnter new name: ");
strcpy(myStud->name,getString(1,19));
printf("\n The values is now %s",myStud->name);
}
return (EXIT_SUCCESS);
}
char * getString(int minChars, int maxChars)
{
char string[maxChars+1];
scanAgain:
scanf("%s",&string);
if(strlen(string)<minChars)
{
printf("\nToo few symbols, try again: ");
goto scanAgain;
}
if(strlen(string)>maxChars)
{
printf("\nToo many symbols, try again: ");
goto scanAgain;
}
string[maxChars]='\0';
return(string);
}
Output:
Enter new name: Alekasdasd
The values is now Alekasda�#
Enter new name:
im just a beginner so it might be something very simple... might be not.
oh and by the way, using linux and netbeans as SDK, gcc as compiler.
You're returning a pointer to a stack variable.
char * getString(int minChars, int maxChars)
{
char string[maxChars+1];
When getString returns, string is invalid. Your return value points to this invalid string.
Use:
char * getString(int minChars, int maxChars, char * string) {
return string;
}
...
char string[100];
getString(1, 2, string);
Also, goto? Stop that please - use for, while do, do while but not goto
char * getString(int minChars, int maxChars)
{
char string[maxChars+1];
...
return(string);
}
The "string" array here is only allocated for the scope of the getString() function. Once it returns (goes out of scope), it ceases to exist and will be overwritten by the rest of your program. The "return(string)" statement returns the pointer of this data that's not allocated anymore -- not the data itself. This happens due to the implicit array-to-pointer conversion in C.
Instead of doing this, your getString() function should take a char* as an argument, which is allocated in the calling function.
I see two problems with your getString() function:
The string variable must be declared static so that the memory used for it is not released (stack, popped) when the function returns.
The parameter to scanf() you do not want the & token, but simply the pointer to the buffer, string.
That is, change the lines:
char string[maxChars+1];
scanf("%s",&string);
to read
static char string[maxChars+1];
scanf("%s",string);
The reason you do not want the ampersand in the scanf() call is the following from the man page, man 3 scanf:
s Matches a sequence of non-white-space characters; the next
pointer must be a **pointer to character array** that is long enough
to hold the input sequence and the terminating null character
('\0'), which is added automatically. The input string stops at
white space or at the maximum field width, whichever occurs
first.
240 lines is not a "snippet".
As James suggested in his comment, reduce the code to the minimum number of lines needed to reproduce the problem. At that stage the cause of the problem should become obvious to you -- if not try posting again.

Resources