简体   繁体   中英

Segfault when I try to add variables to my struct

I just began starting to code in C and having a lot of difficulties with an assignment. I'm suppose to use malloc and free to create a record database using structures. The structures will act as my database. I need to be able to add and delete records. I also cant use arrays for my structures but can use arrays anywhere else in the code. The teacher gave me an idea on how to lay out the code but I don't understand how to save my inputs to add it to a record. Any help??

I have a lot of my code commented out to trouble shoot. also the the two printf statements on the bottom of main are there for troubleshooting. I can get it to print out first name but soon as I add last name, I get a seg fault. I believe I'm not allocating memory for this to happen but don't fully understand this stuff yet.. PLEASE HELP! Thanks!!!!

The problem lies in "library" variable of type "struct record" initialization or actually the lack of it:

struct record library; //this will hold info for user input

fName and lName members are uninitialized pointers to char. Allocate memory for your buffers and initialize those pointers to point to those buffers. Uninitialized pointers simply point to "some" memory location. When you put data into that location anything can happen! Alternatively provide fixed size buffers in place of those pointers like:

struct record {
    char fName[100];
    char lName[100];
};

That should work as the first step. Next is to use the malloc/free as your assignment says. Revert struct record back to the original format and use malloc to reserve memory for your buffers before passing them to any function or otherwise using them; like so

#define BUFSIZE (100)
library.fName = malloc(BUFSIZE);
library.lName = malloc(BUFSIZE);

After memory reservation you may use them but don't pass more than BUFSIZE number of characters to those buffers.

After you are done with your buffers free the allocated memory:

free(library.fName);
free(library.lName);

After freeing the buffers you may not use them anymore. Also don't use gets(). It doesn't provide any protection for buffer overflows as the maximum buffer size is not passed as a parameter to gets(). It has been deprecated and will be removed from the forthcoming standard C1X as unsafe.

Because you are reading data into uninitialized pointers:

   printf ("Please enter your first name:\n");
   gets(library.fName);
   printf ("Please enter your last name:\n");
   gets(library.lName);

Allocate memory using malloc and use them and free() them once you are done. If you don't need pointers, you can use arrays in your struct .

  1. Please don't gets() as it can't prevent buffer overflow. Use fgets() instead.

  2. int main() should be int main(void) or int main(int argc, char *argv[]) or its equivalent.

None of your struct members have memory allocated to them. For ease, first define them as

char fName[10]; 
char lName[10]; 
etc, 

Once you are comfortable with this, then try memory allocation. (IOW, one concept at a time)

The problem you have having is that you are not actually allocating any memory to store the input. Let's start with your struct:

   struct record{
     char * fName;
     char * lName;
   };         

In memory this struct is just two char pointers. The struct itself is 8 bytes long. The pointers aren't initialized to anything, so they have random values. When you use them as pointers, you will point to a random location in memory.

If you want to actually store the first and last names in your struct, then you could create the struct like this:

   static const int MaxNameLength = 255;
   struct record{
     char fName[MaxNameLength + 1];
     char lName[MaxNameLength + 1];
   };         

Alternately you could use the struct the way that you wrote it, but allocate memory for the buffers and update the pointers. If you did that you would need to do this:

static const int MaxNameLength = 255;
struct Record library;
library.fName = (char *)malloc(MaxNameLength + 1);
library.lName = (char *)malloc(MaxNameLength + 1);

Both these methods are valid, but the advantage to the first method is that you would not need to clean up memory yourself. When the struct goes out of scope all the memory is freed. If you malloc the memory yourself, then you also need to free it.

 struct record{
   char * fName;
   char * lName;
   //char * sAddress;
   //char * city;
   //char * state;
   //int * zip;
   };   

In your structure you are using char * fname

but you input method was not correct you have to do malloc for that

But for a newbie in C

keep fname and lname as char array like

struct record{
       char fName[100];
       char lName[100];
       //char * sAddress;
       //char * city;
       //char * state;
       //int * zip;
       };  

Now your above code works fine ..

fName and lName are pointers, in general you have to allocate memory to each pointers and free memory for each pointer too. If you read or write on a pointer which is unassigned memory segmentation fault will occur, You can create an array like name[20] and use gets function. Allocate memory to lName and fName like malloc(strlen(name)). Later on free in the end. Try to malloc and free in main function as it can create problem (you will learn later on pass by value and pass by refernce issues)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM