[C] FindFirst probleem

Pagina: 1
Acties:

  • arnova
  • Registratie: Augustus 2001
  • Laatst online: 09-09 09:11

arnova

weet veel, maar niet alles

Topicstarter
Ik heb een stukje code geschreven om voor mijn GCC voor Win32 een Borland C compatible findfirst/findnext te maken. Dit omdat de _findfirst van GCC geen attributen mask ondersteund. Nu heb ik het wel werkend maar toch klopt er nog iets helemaal niet (ik heb volgens mij een memory leak) en bovendien is de code niet helemaal schoon. Vooral omdat ik het niet op een nette manier voor elkaar krijg om fblk.name (bv.) te lezen in de routine daarvoor moet ik eerst een "ffblk = *fblk;" doen, ik denk ook dat daar ergens het memory leak probleem zit. Weet iemand hoe ik dit netjes kan oplossen?

Dit is de code voor findfirst (findnext is vrijwel hetzelfde).
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int findfirst(const char *pathname, struct _finddata_t *fblk, unsigned int fattrib)
{
  int done = 0;
  struct _finddata_t ffblk;

  ffattrib=fattrib;
  ffhandle=_findfirst(pathname, fblk);

  ffblk = *fblk;

  if (ffhandle==-1) done==-1;

  while (done!=-1 && (ffblk.attrib!=ffattrib || strcmp(ffblk.name, "..")==0 || strcmp(ffblk.name, ".")==0))
  {
    done = _findnext(ffhandle, fblk);
    ffblk = *fblk;
  }

  return done;
}

ESP PV-Boiler Controller https://github.com/arnova/pvboiler


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Even [C] toegevoegd aan je titel en maak nog even gebruik van de [code]-tag om je code heen

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 10-08 15:15
Twee hints:
- Ooit eens van de -> operator gehoord?
- je werkt met een attribute mask? Maar waarom kijk je dan met != of je mask klopt met de daadwerkelijke attributen, terwijl een mask nu juist bedoelt is om "er overheen te leggen" en dan te kijken of iets geld ja of nee -> dus gebruik een bit-operatie zoals & of iets dergelijks.

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 10-08 15:15
Die code van jouw kan je ook zo schrijven:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
long myFindFirst(char *filespec, struct _finddata_t *fileinfo, int mask)
{
    long hFile;
    
    hFile = _findfirst(filespec, fileinfo);
    if (hFile == -1L)
      return -1L;
    
    while(hFile != -1L)
    {
      if (fileinfo->attrib & mask)
        return hFile;
    
      hFile = _findnext(hFile, filespec);
    }
    
    return -1L;
}

Mocht je dan nog een memory-leak hebben: je moet na het zoeken ook nog findclose aanroepen op je handle, dus iets als:
code:
1
2
3
4
5
6
7
8
long handle;
struct _finddata_t fileInfoBuf;

handle = myFindFirst("C:\\", &fileInfoBuf, _A_HIDDEN);
... doe wat met fileInfoBuf
... je find next dingen ...
// uiteindelijk:
_findclose(handle);

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • arnova
  • Registratie: Augustus 2001
  • Laatst online: 09-09 09:11

arnova

weet veel, maar niet alles

Topicstarter
Hartstikke bedankt! Ik heb die code nu min of meer omgeschreven naar jou voorstel en dat werkt nu goed met die -> (ik was vergeten dat ie bestond, tijd geleden dat ik C heb gebruikt). Ik heb helaas nog wel last van dat memory leakje, waarschijnlijk zit dat dus ergens anders. Ik ga nog maar ff verder zoeken...

ESP PV-Boiler Controller https://github.com/arnova/pvboiler


  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 10-08 15:15
Weet je zeker dat die leek in de je eigen findfirst functie zit? Want hoe heb je dat getest en hoe roep je je findfirst/findnext aan?

Want ik vraag me n.m.l. af waar dan die geheugenlek moet zitten. In de code die je gegeven hebt vinden geen allocaties plaats en alleen _findfirst/_findnext zouden dan geheugen kunnen lekken. Echter, als je _findclose dan geldig aanroept hoort deze de gebruikte resources weer vrij te geven.

Je kan je overigens nog afvragen of een findfirst/findnext wel een gebruikersvriendelijke implementatie is. En op dit moment zul je ook nog eens je mask bij elke aanroep van findnext op moeten geven, terwijl je dit eigenlijk alleen bij de aanroep van findfirst wilt doen.

Een naar mijn idee veel meer voor de hand liggende constructie zou iets zijn in de trant van:

OpenSearch
GetResult
CloseSearch

Zoals bijvoorbeeld:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
OFSHandle openFileSearch(const char *filespec, const int mask);
int getMatchingFile(OFSHandle fs, OFSResult *r);
int closeFileSearch(OFSHandle fs);

typedef struct _OFS
{
    struct _finddate_t findDataBuf;
    long handle;
} OFS, *OFSHandle;

typedef struct _OFSResult
{
    const char *filename;
    const int attributes;
    // etc.
} OFSResult;

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]

Pagina: 1