Search code examples
cpointersstructsegmentation-faultcoredump

Segmentation fault core dumped in C while trying to create memory for a Struct


I'm getting a segmentation fault when trying to run the following code:

C File

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "myData.h"

struct structPointer *sP;
struct structPointer *sSP;
int recordNumber = 0;
int numberOfAccesses = 0;

int main(void) {
    sP = (struct structPointer *) malloc(5 * sizeof(struct structPointer));
    sSP = sP;

    memcpy(sP->name,"Adam Baum",50);
    memcpy(sP->fireNumber,"N1234",10);
    memcpy(sP->street,"Top Secret",25);
    memcpy(sP->city,"Manhattan",25);
    memcpy(sP->state,"New York",25);
    sP++;
    recordNumber++;
    memcpy(sP->name,"Adam Zapel",50);
    memcpy(sP->fireNumber,"S4321",10);
    memcpy(sP->street,"Throat",25);
    memcpy(sP->city,"Manhattan",25);
    memcpy(sP->state,"New York",25);
    sP++;
    recordNumber++;
    memcpy(sP->name,"Al Bino",50);
    memcpy(sP->fireNumber,"W1234",10);
    memcpy(sP->street,"White",25);
    memcpy(sP->city,"Anchorage",25);
    memcpy(sP->state,"Alaska",25);
    sP++;
    recordNumber++;
    memcpy(sP->name,"Anne Teak",50);
    memcpy(sP->fireNumber,"E4321",10);
    memcpy(sP->street,"Oak",25);
    memcpy(sP->city,"Woodville",25);
    memcpy(sP->state,"Wisconsin",25);
    sP++;
    recordNumber++;
    memcpy(sP->name,"Barb Dwyer",50);
    memcpy(sP->fireNumber,"N1234",10);
    memcpy(sP->street,"Keepout",25);
    memcpy(sP->city,"Kilgore",25);
    memcpy(sP->state,"Texas",25);
    recordNumber++;

    while (1){
        int sel;
        printf("MENU\n");
        printf("=====\n");
        printf("1. Print All Records\n");
        printf("2. Print Number of Records\n");
        printf("3. Print Size of Database\n");
        printf("4. Add Record\n");
        printf("5. Delete Record\n");
        printf("6. Print Number of Accesses to Database\n");
        printf("7. Exit\n");
        printf("=====\n");
        printf("Enter selection: ");
        sel = getchar();
        sel = sel-48;
        switch(sel){
            case 1:
                numberOfAccesses++;
                printAllRecords(sP);
                break;
            case 2:
                numberOfAccesses++;
                fprintf(stderr,"There are a Total of %d records\n", recordNumber);
                break;
            case 3:
                numberOfAccesses++;
                printSizeOfDatabase(sP);
                break;
            case 4:
                numberOfAccesses++;
                sP = sSP;
                addRecord(sP);
                break;
            case 5:
                numberOfAccesses++;
                deleteRecord(sP);
                break;
            case 6:
                numberOfAccesses++;
                fprintf(stderr,"The total number of Accesses is %d\n", numberOfAccesses);
                break;
            case 7:
                exit(0);
            case -38:
                printf("Code is reading in LineFeed and displaying Menu again\n");
                break;
            default:
                printf("Error: Input was not a valid selection.\n");
                break;
        }
    }
return 0;
}

int printAllRecords(struct structPointer *addresses){
    int i;
    printf("All Records: ");
    for(i=1;i<recordNumber;i++){
        printf("Address: %d\n", i);
        fprintf(stderr, "Name = \%s\n", addresses-> name);
        fprintf(stderr, "Fire Number = \%s\n", addresses-> fireNumber);
        fprintf(stderr, "Street = \%s\n", addresses-> street);
        fprintf(stderr, "City = \%s\n\n", addresses-> city);
        fprintf(stderr, "State = \%s\n\n", addresses-> state);
    }
    return 1;
}

int printSizeOfDatabase(struct structPointer *addressesAgain) {
    int size = 0;
    int i;
        for (i=1;i<=recordNumber;i++) {
        size += sizeof(addressesAgain->name);
        size += sizeof(addressesAgain->fireNumber); 
        size += sizeof(addressesAgain->street);
        size += sizeof(addressesAgain->city);
        size += sizeof(addressesAgain->state);
        addressesAgain++;
        }
    fprintf(stderr, "The size of the database is %d bytes.\n", size);
    return size;
}

int addRecord(struct structPointer *addressesAgainTimes2){
    char entryName;
    char entryFireNumber;
    char entryStreet;
    char entryCity;
    char entryState;
    recordNumber++;
    struct structPointer *theStruct;
    theStruct = (struct structPointer *) malloc ((recordNumber+1) * sizeof(struct structPointer));
    addressesAgainTimes2 = sSP;
    int i;
    for (i=1;i<recordNumber;i++){
        memcpy(theStruct->name,addressesAgainTimes2->name,50);
        memcpy(theStruct->fireNumber,addressesAgainTimes2->fireNumber,10);
        memcpy(theStruct->street,addressesAgainTimes2->street,25);
        memcpy(theStruct->city,addressesAgainTimes2->city,25);
        memcpy(theStruct->state,addressesAgainTimes2->state,25);
        if(i==recordNumber-1){
            theStruct++;}
        else{
            theStruct++;
            addressesAgainTimes2++;}
    }
    printf("Enter the Name of the New Record: \n");
    scanf("%s",&entryName);
    memcpy(theStruct->name,&entryName,50);
    printf("Enter the Fire Number of the New Record: \n");
    scanf("%s",&entryFireNumber);
    memcpy(theStruct->fireNumber,&entryFireNumber,10);
    printf("Enter the Street of the New Record: \n");
    scanf("%s",&entryStreet);
    memcpy(theStruct->street,&entryStreet,25);
    printf("Enter the City of the New Record: \n");
    scanf("%s",&entryCity);
    memcpy(theStruct->city,&entryCity,25);
    printf("Enter the State of the New Record: \n");
    scanf("%s",&entryState);
    memcpy(theStruct->state,&entryState,25);
    addressesAgainTimes2=theStruct;
    printf("Record has been added.");
    return 0;
}

int deleteRecord(struct structPointer *addressesAgainTimes3){
    struct structPointer *anotherStruct;
    anotherStruct = (struct structPointer *) malloc ((recordNumber+1) * sizeof(struct structPointer));
    int i;
    for(i=0;i<5;i++){
        memcpy(anotherStruct->name,addressesAgainTimes3->name,50);
        memcpy(anotherStruct->fireNumber,addressesAgainTimes3->fireNumber,10);
        memcpy(anotherStruct->street,addressesAgainTimes3->street,25);
        memcpy(anotherStruct->city,addressesAgainTimes3->city,25);
        memcpy(anotherStruct->state,addressesAgainTimes3->state,25);
        addressesAgainTimes3++;
    }
    addressesAgainTimes3=anotherStruct;
    recordNumber--;
    printf("Record has been deleted.");
    return 0;
}

Header File:

#include <stdio.h>
#include <stdlib.h>

struct structPointer{
    char *name;
    char *fireNumber;
    char *street;
    char *city;
    char *state;
};

This program is supposed to create a chunk of memory where I can store a struct and display a menu where I can add/remove entries from that struct.


Solution

  • Your structPointer member fields are POINTERS to strings, but they are NEVER allocated any memory. You then use memcpy() in effect copying to an UNDEFINED memory.

    Changing your structure as follows will resolve that specific issue:

    struct structPointer{
        char name[SOME_APPROPRIATE_NAME_LENGTH];
        char fireNumber[SOME_APPROPRIATE_NUMBER_LENGTH];
        char street[SOME_APPROPRIATE_STREET_LENGTH];
        char city[SOME_APPROPRIATE_CITY_LENGTH];
        char state[2];
    };