在尝试为Struct创建内存时,C中的分段故障核心被转储

时间:2014-10-10 22:10:38

标签: c pointers struct segmentation-fault coredump

尝试运行以下代码时出现分段错误:

C档

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

标题文件:

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

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

这个程序应该创建一个内存块,我可以存储一个结构并显示一个菜单,我可以在该菜单中添加/删除该结构中的条目。

4 个答案:

答案 0 :(得分:2)

如果你不想分别初始化struct成员或管理他们的内存,那么它们应该是数组而不是指针:

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

答案 1 :(得分:1)

您的structPointer成员字段是字符串的POINTERS,但它们永远不会分配任何内存。然后使用memcpy()实际复制到UNDEFINED内存。

如下更改结构将解决该特定问题:

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

答案 2 :(得分:0)

初始化时,为结构分配空间五次,但在结构中,char *(如名称)是未分配的指针。你应该为他们分配空间(并在清理时释放它们)。使用strdup或malloc / memcpy。如果它们是固定大小,则将它们声明为固定大小的数组,然后它们也可以。

答案 3 :(得分:0)

将您的struct成员作为数组,或者在复制之前为每个成员单独分配内存。