0

我有一个关于释放为结构数组分配的内存的新手问题。这是代码:

typedef struct {
    char code[6];
    char name[31];
    char cname[31];
    int anno;

} cliente;

cliente *readcostumers(char*filename,int * dim) {
    int i;
    cliente *d;
    cliente temp;
    FILE*fp;
    fp=fopen(filename,"r");
    *dim=0;
    //count the number of lines 
    while(fscanf(fp,"%s %s %s %d", temp.code, temp.name, temp.cname,&(temp.anno))==4)
        (*dim)++;
    rewind(fp);
    //allocate "dim" struct
    int ss = sizeof(cliente);
    d = (cliente*)malloc(ss * (*dim));
    cliente *currCli = d;
    //assign lines to struct
    for(i=0; i<*dim; i++) {
        fscanf(fp,"%s %s %s %d",currCli->code, currCli->name, currCli->cname, &(currCli->anno));
        currCli = currCli + ss;
    }
    fclose(fp);
    return d;
}

这段代码基本上读取一个文本文件,有任意数量的行,用特定的模式格式化,并将内容分配给 strcut 数组cliente

这似乎工作正常,除非我释放先前分配的内存:

int main () {
    int x,i;


    cliente *f = readcostumers("c:/temp/clienti.txt",&x);
    int len = sizeof(cliente);
    for(i=0; i<x; i++) {        
        printf("\n%s %s %s %d",(f + len*i)->code, (f + len*i)->name, 
               (f + len*i)->cname, (f + len*i)->anno);      
    }
    free(f);
}

最后一条语句 free(f) 会导致 SIGTRAP 异常,尽管打印的值是从文件中正确读取的。

文件内容是这样的:

A3789 Paolo Rossi 2001
X478D Marcantonio Bianchi 2004

错误在哪里?

4

2 回答 2

1

当您增加currCliin时,readcostumers您应该使用1并且 inmain您不应该将索引与len. 这些由语言处理。这两个错误相互补偿,但与此同时,您正在分配的内存之外进行访问,并且很可能会覆盖堆分配算法的内部管理。最终导致free.

查看该valgrind工具,因为它完美地发现了这些错误。

于 2013-06-04T20:19:37.667 回答
0

你在这里做什么?

 currCli = currCli + ss;

您应该将指针增加 1,而不是您分配的数组中元素的大小。(该语言会根据所指向对象的大小自动缩放指针添加。)这会导致写入分配区域之外,进而导致内存损坏,以及 SIGTRAP 或核心转储或其他类似问题。

于 2013-06-04T20:19:44.903 回答