Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 当我尝试将变量添加到结构时出现SEGFULT_C_Struct_Malloc_Free_Memcpy - Fatal编程技术网

C 当我尝试将变量添加到结构时出现SEGFULT

C 当我尝试将变量添加到结构时出现SEGFULT,c,struct,malloc,free,memcpy,C,Struct,Malloc,Free,Memcpy,我刚开始用C语言编写代码,在完成作业时遇到了很多困难。我假设使用malloc和free创建一个使用结构的记录数据库。这些结构将充当我的数据库。我需要能够添加和删除记录。我也不能对我的结构使用数组,但可以在代码中的任何其他地方使用数组。老师给了我一个如何布置代码的想法,但我不知道如何保存输入以将其添加到记录中。有什么帮助吗 我的很多代码都被注释掉了,以便排除故障。main底部的两个printf语句也用于故障排除。我可以让它打印出我的名字,但一旦我加上姓氏,我就会得到一个seg错误。我相信我没有为这

我刚开始用C语言编写代码,在完成作业时遇到了很多困难。我假设使用malloc和free创建一个使用结构的记录数据库。这些结构将充当我的数据库。我需要能够添加和删除记录。我也不能对我的结构使用数组,但可以在代码中的任何其他地方使用数组。老师给了我一个如何布置代码的想法,但我不知道如何保存输入以将其添加到记录中。有什么帮助吗


我的很多代码都被注释掉了,以便排除故障。main底部的两个printf语句也用于故障排除。我可以让它打印出我的名字,但一旦我加上姓氏,我就会得到一个seg错误。我相信我没有为这件事分配内存,但我还没有完全理解这件事。。请帮忙!谢谢

因为您正在将数据读入未初始化的指针:

   printf ("Please enter your first name:\n");
   gets(library.fName);
   printf ("Please enter your last name:\n");
   gets(library.lName);
使用
malloc
分配内存,并在完成后使用它们和
free()
它们。如果不需要指针,可以在
结构中使用数组

  • 请不要
    get()
    ,因为它不能防止缓冲区溢出。改用
    fgets()

  • int main()
    应为
    int main(void)
    int main(int argc,char*argv[])
    或其等效项


  • 没有为结构成员分配内存。为方便起见,首先将其定义为

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

    一旦您对此感到满意,那么尝试内存分配。(注意,一次一个概念)

    您遇到的问题是您实际上没有分配任何内存来存储输入。让我们从结构开始:

       struct record{
         char * fName;
         char * lName;
       };         
    
    在内存中,这个结构只是两个字符指针。结构本身有8个字节长。指针没有初始化为任何值,因此它们具有随机值。当您使用它们作为指针时,您将指向内存中的随机位置

    如果您希望在结构中实际存储名字和姓氏,则可以按如下方式创建结构:

       static const int MaxNameLength = 255;
       struct record{
         char fName[MaxNameLength + 1];
         char lName[MaxNameLength + 1];
       };         
    
    或者,您可以按照编写结构的方式使用它,但是为缓冲区分配内存并更新指针。如果您这样做了,您需要这样做:

    static const int MaxNameLength = 255;
    struct Record library;
    library.fName = (char *)malloc(MaxNameLength + 1);
    library.lName = (char *)malloc(MaxNameLength + 1);
    
    这两种方法都是有效的,但第一种方法的优点是您不需要自己清理内存。当结构超出范围时,将释放所有内存。如果你自己malloc内存,那么你也需要释放它

     struct record{
       char * fName;
       char * lName;
       //char * sAddress;
       //char * city;
       //char * state;
       //int * zip;
       };   
    
    在您的结构中,您使用的是char*fname

    但您的输入方法不正确,您必须为此执行malloc

    但是对于C语言的新手来说

    将fname和lname保持为char数组

    struct record{
           char fName[100];
           char lName[100];
           //char * sAddress;
           //char * city;
           //char * state;
           //int * zip;
           };  
    
    现在,您的上述代码运行良好。

    问题在于“struct record”初始化类型的“library”变量,或者实际上缺少该变量:

    struct record library; //this will hold info for user input
    
    fName和lName成员是指向char的未初始化指针。为缓冲区分配内存并初始化这些指针以指向这些缓冲区。未初始化的指针只是指向“某个”内存位置。当您将数据放入该位置时,任何事情都可能发生!或者,提供固定大小的缓冲区来代替以下指针:

    struct record {
        char fName[100];
        char lName[100];
    };
    
    这应该是第一步。下一步是使用malloc/free,正如您的任务所述。将struct record恢复为原始格式,并在将缓冲区传递给任何函数或以其他方式使用它们之前,使用malloc为缓冲区保留内存;像这样

    #define BUFSIZE (100)
    library.fName = malloc(BUFSIZE);
    library.lName = malloc(BUFSIZE);
    
    在内存保留之后,您可以使用它们,但传递给这些缓冲区的字符数不能超过BUFSIZE

    使用完缓冲区后,释放分配的内存:

    free(library.fName);
    free(library.lName);
    
    释放缓冲区后,您可能不再使用它们。
    也不要使用get()。它不为缓冲区溢出提供任何保护,因为最大缓冲区大小没有作为参数传递给gets()。它已被弃用,并将作为不安全因素从即将推出的标准C1X中删除。

    fName和lName是指针,通常您必须为每个指针分配内存,并为每个指针释放内存。如果在未分配内存的指针上读写,将出现内存分段故障, 您可以创建一个类似名称[20]的数组并使用gets函数。将内存分配给lName和fName,如malloc(strlen(name))。后来终于自由了。尝试在main函数中malloc和free,因为这可能会产生问题(稍后您将了解传递值和传递引用问题)