自由功能导致SIGTRAP

时间:2013-06-04 20:13:04

标签: c free dynamic-memory-allocation

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

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

错误在哪里?

2 个答案:

答案 0 :(得分:1)

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

查看valgrind工具,因为它可以完美地找到这些错误。

答案 1 :(得分:0)

你在这做什么?

 currCli = currCli + ss;

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