segmentation fault in C - c

I am trying to write this code, but it gives me segmentation fault after running the program, could you please help to sort it out?
#include <stdio.h>
#include <string.h>
typedef struct{
int salary;
char* name;
} employee ;
int main(){
employee p[2];
int i;
for(i=0;i<2; i++){
printf("enter sal ");
scanf("%d", &p[i].salary);
printf("enter name ");
scanf("%s", &p[i].name);
}
for(i=0;i<2; i++){
printf("p %d",p[i].salary);
printf("p %s",p[i].name);
}
return 0;
}

You need to allocate memory for the name field: p[i].name = (char*)malloc(MAX_NAME_LEN)
Also, the scanf("%s", &p[i].name) should read scanf("%s", p[i].name).

The structure field name is just a wild character pointer.
char* name;
you are reading the user input as:
scanf("%s", &p[i].name);
into the memory pointed by name which could be anywhere.
To fix this you need to dynamically allocate memory pointed to by name or you can change name to a char array of size one greater than the max length of the name possible.
char name[MAX];

You don't need the & operator when scanf'ing to pointer. And you need to malloc p[i].name
scanf("%s", p[i].name);

You are not allocating memory for char* name. change your data structure to
typedef struct
{
int salary;
char name[50];
}
or allocate memory using malloc

You forgot to allocate memory for p[i].name.

You have to reserve memory for the name member of each instance of employee:
p[i].name = (char*)malloc(expected_max_size);
just before the scanf for that variable. Declaring a pointer to char char* does not assign memory for the actual string pointed to, but just for the pointer itself, and in your example it is not initialized. By using malloc you reserve a piece of memory and makes the pointer point to it. You have to be careful with bounds checking, because you have to reserve the memory beforehand, enough to hold what the user is writing.

You need to allocate memory for the "name" string in your structure. Do this using malloc() or by declaring name as an array of a given size (char name[SIZE]).

Related

Use of Malloc in C and pointer member error

#include <stdio.h>
#include <stdlib.h>
struct Album {
char* title;
}
int main(){
int i, size;
struct Album* pAlbum;
printf("Enter the number of album: ");
scanf_s("%d", &size);
pAlbum = malloc(sizeof(pAlbum) * size);
for(i=0; i<size; i++) {
printf("Enter the album title: ");
scanf_s("%p", pAlbum[i].title);
}
free(pAlbum);
return 0;
}
I want to let the user enter the title for as many albums as they want. The error is that scanf only comes up once for pAlbump[i].tittle for the loop. I'm i allocating the memory incorrectly?
pAlbum = malloc(sizeof(pAlbum) * size);
This allocates size pointers. But you wish to allocate size structs.
Your allocation should therefore be
pAlbum = malloc(sizeof(*pAlbum) * size);
or
pAlbum = malloc(sizeof(struct Album) * size);
or
pAlbum = calloc(size, sizeof(struct Album));
Once you've dealt with that, you will need to allocate memory to store each string in the struct. That's going to need separate calls to malloc.
for(i=0; i<size; i++) {
printf("Enter the album title: ");
pAlbum[i].title = malloc(...); // you need to decide how much to allocate
scanf_s("%s", pAlbum[i].title); // hmm, this simply begs a buffer overrun ...
}
And then you'd need to free each of the title strings that you allocated in that loop before freeing the array of structs.
Before using data member title of the structure in statement
scanf_s("%p", pAlbum[i].title);
you have to allocate memory that will be pointed to by this data member and where you are going to store entered data.
And you have to use tag struct before name Album in statement
pAlbum = malloc(sizeof( struct pAlbum) * size);
And instead type specifier "%p" you have to use %s that to enter a string.
First, if you are not to add extra members to your structure then just pull out the char* to the outside and use it. If you want the type to be called Album, you could write typedef char *Album;. You are allocating memory to hold pointers to strings but not the memory that holds the actual strings. Your scanf uses the wrong format %p, use %s to read a string of characters; the scanf is reading to an unallocated piece of memory so that's going to cause a runtime error.
To allocate memory for n items, use calloc (for contiguous allocate). calloc allocates a block of memory for an array of n elements, each of them elem_sizebytes long.
calloc(n, elem_size);
You should know how many bytes each title is or use a maximum number of bytes in your code. There exists a function that will take care of the memory allocation for you but it's not part of the standard. It's called strdup.
You have two options, either make title member an array of fixed size
struct Album {
char title[100];
}
and use scanf_s this way
scanf_s("%99s", pAlbum[i].title, _countof(pAlbum[i].title));
Or, use malloc
char tmp[100];
if (scanf_s("%99s", tmp, _countof(tmp)) == 1)
pAlbum[i].title = strdup(tmp);
Also, to allocate size structs, do as David Heffernan said.

Taking string input in char pointer

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char *s;
printf("enter the string : ");
scanf("%s", s);
printf("you entered %s\n", s);
return 0;
}
When I provide small inputs of length up to 17 characters (for example "aaaaaaaaaaaaaaaaa") the program works perfectly fine but on providing inputs of larger lengths, it gives me a runtime error saying "main.c has stopped working unexpectedly".
Is there some problem with my compiler (codeblocks) or my pc (windows 7)? Or is it somehow related to the input buffer of C?
It's undefined behaviour as the pointer is uninitialized. There's no problem with your compiler but your code has problem :)
Make s point to valid memory before storing data in there.
To manage buffer overflow, you can specify the length in the format specifier:
scanf("%255s", s); // If s holds a memory of 256 bytes
// '255' should be modified as per the memory allocated.
GNU C supports an non-standard extension with which you don't have to allocate memory as allocation is done if %as is specified but a pointer to pointer should be passed:
#include<stdio.h>
#include<stdlib.h>
int main() {
char *s,*p;
s = malloc(256);
scanf("%255s", s); // Don't read more than 255 chars
printf("%s", s);
// No need to malloc `p` here
scanf("%as", &p); // GNU C library supports this type of allocate and store.
printf("%s", p);
free(s);
free(p);
return 0;
}
the char pointer is not initialized, you should dynamiclly allocate memory to it,
char *s = malloc(sizeof(char) * N);
where N is the maximum string size you can read, And its not safe to use scanf
without specifying the maximum length for the input string, use it like this,
scanf("%Ns",s);
where N same as that for malloc.
You are not allocating any memory to the character array so first try to get memory by calling malloc() or calloc(). then try to use it.
s = malloc(sizeof(char) * YOUR_ARRAY_SIZE);
...do your work...
free(s);
You need to allocate enough memory for buffer where your pointer will point to:
s = malloc(sizeof(char) * BUF_LEN);
and then free this memory if you do not need it anymore:
free(s);
You're not allocating memory for your string, and thus, you're trying to write in a non-authorized memory address. Here
char *s;
You're just declaring a pointer. You're not specifying how much memory to reserve for your string. You can statically declare this like:
char s[100];
which will reserve 100 characters. If you go beyond 100, it will still crash as you mentionned for the same reason again.
The problem is with your code .. you never allocate memory for the char *. Since, there is no memory allocated(with malloc()) big enough to hold the string, this becomes an undefined behavior..
You must allocate memory for s and then use scanf()(I prefer fgets())
#include"stdio.h"
#include"malloc.h"
int main(){
char *str;
str=(char*)malloc(sizeof(char)*30);
printf("\nENTER THE STRING : ");
fgets(str,30,stdin);
printf("\nSTRING IS : %s",str);
return 0;
}
The code in C to read a character pointer
#include<stdio.h>
#include<stdlib.h>
void main()
{
char* str1;//a character pointer is created
str1 = (char*)malloc(sizeof(char)*100);//allocating memory to pointer
scanf("%[^\n]s",str1);//hence the memory is allocated now we can store the characters in allocated memory space
printf("%s",str1);
free(str1);//free the memory allocated to the pointer
}
I was getting this problem. I tried this code below and it worked:
char *text;
scanf("%s", *&text);
I dont know how it worked. I just felt like doing it.

c reading string input error

struct employee {
int employeeId;
double payrate;
char *inputname;
};
int main (void){
//remember the struct before employee
struct employee davidB;
fgets(davidB.inputname, 20, stdin);
davidB.employeeId = 1;
davidB.payrate = 45020.50;
printf("The employees name is %s\n The employees id num is %d\n The employees payrate is %f\n", davidB.inputname, davidB.employeeId, davidB.payrate);
struct employee ericG;
printf("Please enter employee name, id number, and payrate\n");
scanf("%s", ericG.inputname);
scanf("%d", &ericG.employeeId);
scanf("%lf", &ericG.payrate);
printf("The employees name is %s\n The employees id num is %d\n The employees payrate is %f\n", ericG.inputname, ericG.employeeId, ericG.payrate);
return 0;
}
My questions involve:
fgets(davidB.inputname, 20, stdin);
scanf("%s", ericG.inputname);
Why does the first one work and why does the second one cause stack overflow? Furthermore, when can I directly assign a "string" to a pointer, and when does it need to be a pre-defined char array?
for example:
const char *string = "Hey"; //works? so can't I do the same with the scanf above?
You need to allocate memory in order to use those functions, otherwise you get stack overflow since this pointer (davidB.inputname) is pointing to garbage.
One option would be to define it like char inputname[21]; but this will only work for the fgets function since you can limit the number of chars your read.
But with scanf there is nothing you can do unless you can be 100% on the size of the string you're about to read so it's better avoid it otherwise.
It is just random luck that one way works, but the other does not. Both methods are incorrect, as you are not allocating any memory for inputname to point to. So, the functions are just inputting data to some random memory location.
The const char *string = "Hey" works because this is static data, and the compiler is allocating space for it somewhere.
You haven't allocated memory for `inputname. So both invoke undefined behaviour. So both don't work, not in legal C anyway.
But when you directly assign like this:
const char *string = "Hey";
string merely points to a string literal. So there's no need for memory allocation there.
So in this way, you can directly assign to the struct member:
struct employee davidB;
davidB.inputname = "Eric"; // Thiis is valid.
davidB.employeeId = 1;
davidB.payrate = 45020.50;
Otherwise, you have to dynamically allocate memory for inputname:
struct employee davidB;
davidB.inputname = malloc(256);
fgets(davidB.inputname, 256, stdin);
davidB.employeeId = 1;
davidB.payrate = 45020.50;

Using a pointer in a struct

While I was inputting "stuList[1].name", an error occurred and the program crashed. How do I fix this?
#include <stdio.h>
#include <conio.h>
typedef struct student
{
int id;
char *name;
float percentage;
} student;
int main()
{
student stuList[3];
stuList[0].name = "vermidonhapic";
stuList[2].name = "didiervermiyer";
scanf("%s\n",&stuList[1].name);
printf(" name is: %s \n", stuList[0].name);
printf(" name is: %s \n", stuList[2].name);
printf(" name is: %s \n", stuList[1].name);
system("PAUSE");
}
In this command: scanf("%s\n",&stuList[1].name);
You are scanning string from input without actually allocating the required memory.
This results in trying to write the data in an unkown address, which is not yours, which results in a segmentation fault.
To fix it, first allocate memory: stuList[1].name = malloc(MAX_LENGTH);, and only after: scan the string from stdin.
name is just a pointer that isn't pointing to memory you own, so writing through it will corrupt memory. You need to allocate some memory on it with malloc(), or make it an array rather than a pointer.
stuList[1].name is an invalid pointer as it has not been initialized to point to a valid object.
You should dynamically allocate memory (through malloc function) for stuList[1].name so scanf could write to an allocated object.
stuList[1].name = malloc(size_enough_to_store_your_string);
Moreover, stuList[1].name is a pointer to char so you should use stuList[1].name and not &stuList[1].name (pointer to a pointer to char) in your scanf function call.
You forgot to allocate memory for stuList[1].name. You need to allocate it from the heap with malloc or stack allocate it.
stuList[1].name = malloc(MAX_NAME_LENGTH);//heap allocation
//use stuList[1].name
free(stuList[1].name);
char buffer[MAX_NAME_LENGTH];//stack allocation
stuList[1].name = buffer;
I've omitted all error checking, protection against over-running buffers etc.
Since stuList[1].name is a pointer, you are incorrect in taking its address in your scanf.

Copy a string into a char array

Hello i want to copy the input of a user into an array of char which is defined in a struct. Sincerly i have no idea how to do this.
#include <stdio.h>
#include <stdlib.h>
int main ()
{
struct employee
{
char firstname[11];
char lastname[11];
char number[11];
int salary;
}
int i;
int nemps;
const int maxemps = 5;
struct employee* emps[maxemps];
printf("How many employees do you want to store?(max:5): ");
scanf("%d", nemps);
for (i = 0; i < nemps; i++)
{
printf("Employee 1./nLast name:");
scanf("....")// Read the string and copy it into char lastname[]
}
}
First off struct employee* emps[maxemps]; creates an array of pointers to struct employee with array size maxemps. You haven't actually set aside any space in memory for the actual structs, just the pointers that will point to them. To dynamically allocate space on the heap for your structs so you can use them in a meaningful way, you'll need to loop over a call to malloc() like so:
for (i = 0; i < maxemps; i++) {
emps[i] = malloc(sizeof(struct employee));
}
You'll also want a similar loop at the end of your program which will free() each pointer.
Next, when you are getting input from a user you really want to be using fgets() over scanf() because fgets() allows you to specify the number of characters to read in so you can prevent overflows on your destination buffer.
Update
If you want to work with a single struct employee without the use of pointers this is accomplished by declaring one or more struct employee on the stack and then using the . member access operator as follows:
struct employee emp;
fgets(emp.lastname, sizeof(emp.lastname), stdin);
Update2
I found a number of errors in your code. Please see this link for a working sample with comments.
You only need:
scanf("%10s", (emps[i])->last_name);
Here "%10s" denotes a string with a maximum length of 10, and it will load the string to last_name.
In C the string is represented as a char array, with '\0' as the end.
Using scanf here is vulnerable to buffer attacks if the user-input is longer than 10: http://en.wikipedia.org/wiki/Scanf#Security, so you need to assign a maximum length to the format.

Resources