我的任务是写一个显示用户输入的未知记录数的文件。每条记录都有以下字段:名字、姓氏、地址、城市、州、邮政编码和电话号码。
我认为最好的方法是用上面的字段定义一个struct记录,然后声明一个Records数组,该数组包含用户输入的所有记录。为此,我将使用循环来获取每条记录的每个字段的输入,然后如果用户希望继续在Record数组中动态分配额外的空间并继续,直到用户输入no。我在第行遇到访问冲突写入位置错误:

scanf("%s", records[i]->fname);

我的密码怎么了?
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct Record;

struct Record
    {
        char fname[51];
        char lname[51];
        char address[51];
        char city[51];
        char state[51];
        int zipcode;
        int phoneNumber;
    };

int main()
{
    FILE *fileWriter;
    const char filename[] = "data.txt";
    char answer = 'y';
    int size = 1;
    int i = 0;
    struct Record **records;
    records = malloc(sizeof(*records)*(size));

    while(answer == 'y' || answer == 'Y')
    {
        printf("First Name: \n");
        scanf("%s", records[i]->fname);

        printf("Last Name: \n");
        scanf("%s", records[i]->lname);

        printf("Address: \n");
        scanf("%s", records[i]->address);

        printf("City: \n");
        scanf("%s", records[i]->city);

        printf("State: \n");
        scanf("%s", records[i]->state);

        printf("Zipcode: \n");
        scanf("%d", records[i]->zipcode);

        printf("Phone Number: \n");
        scanf("%d", records[i]->phoneNumber);
        //stores all record info

        printf("Are there anymore records? [y/n] ");
        answer = getchar();
        if(answer == 'y' || answer == 'Y')
        {
            size++;
            records[i++];
            printf("\n");
        }
        records = realloc(records,sizeof(*records)*(size));
    }

    //open file
    fileWriter = fopen(filename,"wb");

    if(fileWriter != NULL)
    {
        if(fwrite(records,sizeof(*records),size,fileWriter) != 1)
        {
            fprintf(stderr, "Failed to write to %s\n", filename);
            exit(1);
        }
        fclose(fileWriter);
    }
    else
    {
        printf("Error opening file.");
    }
}

编辑版本
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

struct Record
    {
        char fname[51];
        char lname[51];
        char address[51];
        char city[51];
        char state[51];
        int zipcode;
        int phoneNumber;
    };




int main()
{
    FILE *fileWriter;
    const char filename[] = "data.txt";
    char answer = 'y';
    int size = 1;
    int i = 0;
    struct Record *records = NULL;
    struct Record *records_temp;




    while(answer == 'y' || answer == 'Y')
    {
        struct Record *records_temp = realloc(records,(size)*sizeof(*records));

        if(records_temp == NULL)
        {
            free(records);

        }
        records = records_temp;
        printf("First Name: \n");
        scanf("%s", records[i].fname);
        printf("Last Name: \n");
        scanf("%s", records[i].lname);

        printf("Address: \n");
        scanf(" %[^\n]", records[i].address);

        printf("City: \n");
        scanf("%s", records[i].city);

        printf("State: \n");
        scanf("%s", records[i].state);

        printf("Zipcode: \n");
        scanf("%d", &records[i].zipcode);

        printf("Phone Number: \n");
        scanf("%d", &records[i].phoneNumber);
        //stores all record info

        printf("Are there anymore records? [y/n] ");
        answer = getchar();
        if(answer == 'y' || answer == 'Y')
        {
            size++;
            records[i++];
            printf("\n");
        }

        //open file

    fileWriter = fopen(filename,"wb");

    if(fileWriter != NULL)
    {
        if(fwrite(records,sizeof(*records),size,fileWriter) != 1)
        {
            fprintf(stderr, "Failed to write to %s\n", filename);
            exit(1);
        }
        fclose(fileWriter);
    }
    else
    {
        printf("Error opening file.");
    }
}
}

最佳答案

因为没有为records中的第一个实体分配内存,所以会得到segfault。
所以要解决你需要

records[size-1] = malloc(sizeof(Records));

这样说:
你有一个指向records的指针。
当你这么做的时候
records = malloc(sizeof(*records)*(size));

实际上,您需要指向Recordssize指针。
但这还不够,您需要分配另一个内存来存储实际的Records,因此我们必须
records[size - 1] = malloc(sizeof(Records));

注意:如果Records>1,则应:
int i = 0;
for(;i < size; i++) {
    records[i] = malloc(sizeof(Records));
}

除此之外,正如Arjun已经解释过的,为什么要使用size并修复新内存中的Records **部分,因为如果Records *失败,它将返回realloc,而在最坏的情况下,最终会出现内存泄漏或另一个segfault,无论哪种情况——这对程序都不好。
请参见Arjun's post

关于c - 将数据写入动态数组时出现段错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30448605/

10-12 20:22