Specerion
Specerion

Reputation: 115

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.

Upvotes: 0

Views: 1587

Answers (4)

Ron Pinkas
Ron Pinkas

Reputation: 367

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];
};

Upvotes: 1

Madhu
Madhu

Reputation: 21

Have your struct members as arrays or separately allocate memory for each of them before you copy.

Upvotes: 0

Henno Brandsma
Henno Brandsma

Reputation: 2166

When you initialise it, you allocate room for five times a struct, but within the struct, the char * (like name) are unallocated pointers. You should allocate room for them (and free them when clearing). Either with strdup, or a malloc/memcpy. If they are fixed size, declare them as fixed size arrays, and then they're OK as well.

Upvotes: 0

John Bollinger
John Bollinger

Reputation: 180201

If you don't want to have to initialize the struct members or manage their memory separately, then they should be arrays instead of pointers:

struct structPointer{
    char name[50];
    char fireNumber[10];
    char street[25];
    char city[25];
    char state[25];
};

Upvotes: 2

Related Questions