( SzBlackY | 2018. 04. 06., p – 07:03 )

Néhány WTF:


  if(fp==NULL) {
    fclose(fp);

Miért akarod lezárni a NULL-t?


record * fst_rec = NULL, * act_rec = NULL, * new_rec = NULL, * prev_rec = NULL;

Miért jó, hogy vannak globális változóid? Szüntesd meg őket és tedd őket paraméterré/visszatérési értékké.


    tmp.id = act_rec -> id;
    strcpy(tmp.name, act_rec -> name);
    tmp.goals = act_rec -> goals;
    fwrite(&tmp, sizeof(temp), 1, fp);
  }

Minek másolod ki a tmp struktúrába? Így gyakorlatilag ugyanazt a memóriatartalmat írod ki (+/- a next, ami valami konstans állandó szemét lesz). [egyébként itt lehet a gond is, utána ugyanis szépen ezt olvasod vissza és nem inicializálod a visszaolvasáskor a next értéket, úgyhogy szépen kimutathatsz belőle a nagy világba]

Itt adtam fel...

Ha rám hallgatsz: oszd további problémákra, pl. a beolvasást írd át úgy, hogy legyen egy külön függvényed, ami pontosan egy rekordot beolvas és visszaadja a rá mutató pointert (inkább sikeres/fájl vége/hiba visszatérési értéknek, a pointerre mutató pointert meg kapja meg paraméterként), akkor a fájl beolvasós függvényed lényegesen egyszerűbb, mint a mostani globális state-el való játék (pszeudókód):


last_rec = first_rec = read_one_record();
while(!fp) {
   new_rec = read_one_record();
   last_rec->next = new_rec;
}
return first_rec;

A NULL helyett érdemes lehet egy jól definiált (az lehet globális konstans változó) értéket használni listavégnek, pl. ha biztosan nincs 0 értéked, használd a "0 id-jű rekord a vége" megoldást [aminek a next-je önmagára mutat]: így ha a többi rekord nem mutat ki a memóriából, akkor az egész láncod a saját memóriarészedben lesz, és ha bárhol hibázol, nem elszáll SIGSEG-gel, hanem végtelen ciklusba megy :)

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)