C 使用free()时获取核心转储

C 使用free()时获取核心转储,c,pointers,struct,malloc,coredump,C,Pointers,Struct,Malloc,Coredump,我正在做一个学校作业,司机和头文件一起交给了我。我的工作是完成从文本文件中读取数据,然后搜索名称并返回电子邮件地址的功能。这是一个使用指针和结构的巨大练习 程序读入一个包含姓名和电子邮件地址的文本文件,然后使用malloc()动态创建一个结构数组。struct卡由两个字符指针构成,我使用strlen(),malloc()内存查找数据长度,并将结构分配给给定的内存地址 在打印完姓名和电子邮件并即将释放()内存之前,一切似乎都很正常。每次我都会收到一条中止(核心转储)消息。我不知道会是什么问题 我在

我正在做一个学校作业,司机和头文件一起交给了我。我的工作是完成从文本文件中读取数据,然后搜索名称并返回电子邮件地址的功能。这是一个使用指针和结构的巨大练习

程序读入一个包含姓名和电子邮件地址的文本文件,然后使用
malloc()
动态创建一个结构数组。
struct卡由两个字符指针构成,我使用
strlen()
malloc()
内存查找数据长度,并将结构分配给给定的内存地址

在打印完姓名和电子邮件并即将释放()内存之前,一切似乎都很正常。每次我都会收到一条中止(核心转储)消息。我不知道会是什么问题

我在
free()
之前放置了一个
printf()
,尝试跟踪问题的位置,但它似乎是在名称/电子邮件打印输出期间发生的,或者是在它发生之后发生的,因为我的
printf()
测试点是
free()
之前的一行,从未执行

我假设驱动程序是正常的,它与我的功能有关。 有人想试试看吗

    //Main
    #include <stdio.h>
    #include <stdlib.h>
    #include "lab9utils.h"

    int main(int argc, char * argv[]) {

        // Variable declarations.
        struct Card * cards;
        int size;
        int k;
        char * email;

        // Make sure we have 2 extra command-line paramgers.
        if (argc < 3) {
            printf("Usage:  ./lab9.exe <data_filename> <name_to_lookup>");
            return 0;
        }

        // Get the cards and do the lookup.
        cards = getCards(argv[1], &size);
        email = lookup(cards, argv[2], size);

        // Display the output message ("sorry!" or "name -> email").
        if (email == NULL) {
            printf("Sorry, that name was not in the list of cards.\n");
        } else {
            printf("%s -> %s\n", argv[2], email);
        }

        // Free the memory used by the structures.
        k = 0;
        printf("Test Point#1");
        for (k = 0; k < size; k++) {
            free(cards[k].name);
            free(cards[k].email);
        }
        printf("Test Point#2");
        free(cards);

        return 0;
    }





  // Header

    #ifndef LAB9UTILS_H
    #define LAB9UTILS_H

    struct Card {
        char * name;
        char * email;
    };

    struct Card * getCards(char * filename, int * size);
    char * lookup(struct Card * cards, char * name, int size);

    #endif


   //  Functions

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "lab9utils.h"

    struct Card * getCards(char * filename, int * size_return) {

        int i,size;
        char cTempName[51]={0};
        char cTempEmail[51]={0};

        size = 0;

        //  I/O Setup   
        FILE *fp; 
        fp = fopen(filename,"r");

        //  error checking
        if(fp == NULL)
        {
            perror("Error in opening file");
            return(NULL);
        }

    //  Input Loop      

        while(!feof(fp))
        {
            fscanf(fp,"%s%s",cTempName,cTempEmail);

            size++;
        }   

        size=size-1;

        fclose(fp);

        struct Card * card = (struct Card *)malloc(*size_return * sizeof(struct Card));

        fp = fopen( filename ,"r");

        //  error checking
        if(fp == NULL)
        {
            perror("Error in opening file");
            return(NULL);
        }

        for(i=0;i<size;i++)
            {
                fscanf(fp,"%s%s",cTempName,cTempEmail);
                card[i].name=(char *)malloc((strlen(cTempName)+1));
                card[i].email=(char *)malloc((strlen(cTempEmail)+1));
                strcpy(card[i].name,cTempName);
                strcpy(card[i].email,cTempEmail);

            }

        fclose(fp); 
        //  loop to confirm data was read
        for(i=0;i<size;i++)
                {
                    printf("[ %d ] Name:%s email:%s  Total size:%d\n",i,card[i].name,card[i].email,size);
                }

        *size_return = size;        

        return card;

    }

    char * lookup(struct Card * cards, char * name, int size) {

        int i;

        for(i=0;i<size;i++)
            {
                if (strcmp(cards[i].name,name)==0) 
                {
                    return cards[i].email;
                }
            }

            return NULL;

    }
//Main
#包括
#包括
#包括“lab9utils.h”
int main(int argc,char*argv[]){
//变量声明。
结构卡片*卡片;
整数大小;
int k;
字符*电子邮件;
//确保我们有2个额外的命令行参数。
如果(argc<3){
printf(“用法:./lab9.exe”);
返回0;
}
//获取卡片并进行查找。
卡片=获取卡片(argv[1],&大小);
电子邮件=查找(卡片,argv[2],大小);
//显示输出消息(“对不起!”或“姓名->电子邮件”)。
如果(电子邮件==NULL){
printf(“对不起,该名称不在卡片列表中。\n”);
}否则{
printf(“%s->%s\n”,argv[2],电子邮件);
}
//释放结构使用的内存。
k=0;
printf(“测试点1”);
对于(k=0;k对于(i=0;i而言,
*size\u return
的值是垃圾,因为您仅在函数末尾将其设置为
size

更改此项:

struct Card * card = (struct Card *)malloc(*size_return * sizeof(struct Card));
为此:

struct Card * card = (struct Card *)malloc(size * sizeof(struct Card));

你知道调试器是用来帮助你找到为什么你的程序是核心的,对吗?顺便说一句,在使用它来调整分配大小之前,你从来没有设置过输出变量
*size\u return
,所以你在
malloc
处理不确定数量的数据。例如:
malloc(*size\u return*sizeof(struct Card))
是错误的。没有调试器…讲师让我们用记事本++编程,并在命令行上使用gcc。他不觉得IDE和所有那些像调试器这样的高级附加组件对我们有好处。gdb绝不是一个高级附加调试器,如果你有
gcc
,它应该是可用的。如果它不可用,告诉讲师有一天你会找到它你必须以编写代码为生,越早知道如何使用代码越好。(你的职业生涯中有一半的时间都在使用代码,这不是开玩笑的。)谢谢你。我完全错过了。大约一小时前做了一个小改动,还以为我都学会了。现在就开始工作吧。