Здравствуйте. У меня следующая проблема, есть вот такая прога, задача которой - симулировать работу кэш-памяти
Код:
/* / Sazonov Sergey - in case of wrong kyrrilic 277*/
#include "cachelab.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
extern int getopt(int argc, char *const argv[], const char *optstring);
extern char *optarg;
int ch2i(char x){
int a;
a=x;
return a;
};
struct elements_of_memory{
bool use;
int queue;/* . 1 - .*/
long long address;
};
int power(int s){/* 2- s*/
int answ=1;
for (int i=1;i<=s;i++){
answ=answ*2;
}
return answ;
}
void sort(struct elements_of_memory * Memory, int amount, int last_use){/* queue .. , */
int first_use=Memory[last_use].queue;
for (int i=1;i<=amount;i++){
if (Memory[i].queue < first_use){
Memory[i].queue++;
}
}
Memory[last_use].queue=1;
}
void search_address_and_s(int adds_in_memory,int s,int b,int * current_s,int * current_address){
/* s teg , */
long long value_max_power=16;
int max_power=4;
while (value_max_power < adds_in_memory){
value_max_power=value_max_power*value_max_power;
max_power=max_power*2;
}
*current_address=0;
*current_s=0;
int C=power(b);
for (int i=max_power;i>=b;i--){
if (adds_in_memory - adds_in_memory % value_max_power > 0){
adds_in_memory=adds_in_memory-(int)value_max_power;
if ( i+1 > s+b) {
*current_address=*current_address+(int)value_max_power;
}else{
*current_s=*current_s+(int)value_max_power / C;
}
}
value_max_power=value_max_power/2;
}
}
int search_LRU(struct elements_of_memory * Memory, int address, int E){/* , - */
int i;
for (i=1;i<=E;i++){
if (Memory[i].queue == E){
sort(Memory,E,i);
break;
}
}
return i;
}
void reading_or_writening_in_memory(struct elements_of_memory * Memory,int E,int address, long * hits, long * misses, long * evictions){
/* */
bool have=false;
for (int i=1;i<=E;i++){
if (Memory[i].address == address){/* */
*hits=*hits+1;;
have=true;
break;
}
if (Memory[i].use == false){/* */
*misses=*misses+1;
Memory[i].address = address;
Memory[i].use = true;
sort(Memory,i,i);
have=true;
break;
}
}
if (have == false){/* LRU -*/
Memory[search_LRU(Memory,address,E)].address=address;
*evictions=*evictions+1;
*misses=*misses+1;
}
}
int main (int argc, char **argv)
{
int oc;
int s;
int E;
int b;
char * char_s;
char * char_E;
char * char_b;
char * t;
while ((oc = getopt (argc, argv, "s:E:b:t:")) != -1){
switch (oc)
{
case 's':
char_s=optarg;
case 'E':
char_E=optarg;
case 'b':
char_b=optarg;
case 't':
t=optarg;
}
}
sscanf(char_s,"%x",&s);
sscanf(char_E,"%x",&E);
sscanf(char_b,"%x",&b);
FILE *in=fopen(t,"r");
int amount_s=power(s);
struct elements_of_memory ** Memory=(struct elements_of_memory **)calloc(amount_s,sizeof (struct elements_of_memory *));
for (int i=0;i<=amount_s;i++){/* */
Memory[i]=(struct elements_of_memory *)calloc(E,sizeof (struct elements_of_memory));
for (int j=1;j<=E;j++){
Memory[i][j].use=false;
Memory[i][j].queue=E+1;
Memory[i][j].address=-1;
}
}
char First;
char Second;
int adds_in_memory;
int size_of_data;
char comma;
First=getc(in);
long misses=0;
long hits=0;
long evictions=0;
while (ch2i(First) > 0){
Second=getc(in);
fscanf(in,"%x",&adds_in_memory);
comma=getc(in);
fscanf(in,"%x",&size_of_data);
comma=getc(in);
int current_s,current_address;
search_address_and_s(adds_in_memory,s,b,¤t_s,¤t_address);
if (Second == 'L' || Second == 'S'){
reading_or_writening_in_memory(Memory[current_s],E,current_address,&hits,&misses,&evictions);
}
if (Second == 'M'){
reading_or_writening_in_memory(Memory[current_s],E,current_address,&hits,&misses,&evictions);
hits++;
}
First=getc(in);
}
printSummary(hits, misses, evictions);
fclose(in);
return 1;
}
Проблема в том, что функция printSummary вызывает ошибку "double free or corruption ". Она содержится в cachelab.c и выглядит так:
Код:
void printSummary(int hits, int misses, int evictions)
{
printf("hits:%d misses:%d evictions:%d\n", hits, misses, evictions);
FILE* output_fp = fopen(".csim_results", "w");
assert(output_fp);
fprintf(output_fp, "%d %d %d\n", hits, misses, evictions);
fclose(output_fp);
}
Путем тупого вставления scanf-а выяснено, что fclose и вызывает падение. Если его закомментить, то все работает, но делать этого нельзя.
Прошу помочь, как можно решить сию проблему, учитывая что cachelab.c трогать нельзя?