我有一个关于释放为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
错误在哪里?
答案 0 :(得分:1)
当您在currCli
中增加readcostumers
时,您应该使用1
,而在main
中,您不应该将索引与len
相乘。这些由语言处理。这两个错误相互补偿,但同时您在分配的内存之外访问,并且很可能覆盖堆分配算法的内部管理。最终导致free
崩溃。
查看valgrind
工具,因为它可以完美地找到这些错误。
答案 1 :(得分:0)
你在这做什么?
currCli = currCli + ss;
您应该将指针递增1,而不是您分配的数组中元素的大小。 (该语言根据指向的对象的大小自动缩放指针添加。)这导致在分配区域外写入,这反过来导致内存损坏,SIGTRAP或核心转储或其他类似问题。