Voor een schoolopdrachtje moesten we een filesplitter maken en daarbij ben ik op het volgende gestoten. Mijn filesplitter werkt correct eveneens het aaneenvoegen echter ik merk een eigenaardigheid.
In windows had ik me mistypt en files van 2 bytes groot aangemaakt, nu was de file die ik wou splitten ongeveer 500kiB groot waardoor mijn programma 256 000 files wou aanmaken. Ik laat mijn pc wat rekenen en na een groot aantal minuten zie ik dat hij blijft steken bij 65 532 files. En windows (in mijn geval windows 2000) geeft een memory error. Na debugging constateer ik dat de stapelpointer (register esp) wijst naar adres 0x0000 0000 en een file wil schrijven op plaats 0x0000 0004
De esp wijst vervolgens naar het goede adres 0x0000 0004 maar op het moment dat hij daar enige bits wil schrijven (op dat adres) gaat het helemaal fout. Zoiets had ik uiteraard vermoed want mij lijkt het dat windows enige kritische informatie op de beginadressen van het geheugen heeft staan en dus niet wil dat die daar komen.
Allemaal goed en wel, maar ik wou dat toch even nader onderzoeken. Dus schreef ik gewoon een ander programma dat weer m.b.h.v. fopen() en file aanmaakt om te schrijven en dan het putc() daarin een (random) karakter steekt. Ik schrijf een kort lusje dat meer dan 65 532 laat schrijven en uiteraard sluit ik iedere file met fclose() na het schrijven van het karakter.
Ik compileer voer uit en pats na enkele minuten weer prijs, weer na 65 532 files, weer dezelfde foutmelding en weer betreffende dezelfde adressen.
Nu programmeer ik mooi volgens de ANSI-C standaard dus zeg ik bij mezelf waarom niet vlug even compileren en uitvoeren in linux (redhat 9.0 in mijn geval). Zo gezegd zo gedaan en tot mijn verbazing slaagt mijn programma er daar wel in om meer dan 65 532 files te schrijven (heb het voor 70 000 files getest).
Vervolgens test ik mijn splitter ook op files van een paar MiB's groot en ook hier slaagt hij erin te splitten in het correct aantal files.
Nu vraag ik mij toch een aantal dingen af, waarom zijn er problemen in windows en in linux niet? Kan het bijvoorbeeld zijn dat windows het geheugen slecht beheerd en dat door een bug bijvoorbeeld in windows een slecht stuk geheugen gealloceerd wordt door een willekeurig programma, waardoor windows uiteraard tegenstribbeld en een error geeft.
Of mijn ander vermoeden was dat windows minder geheugen reserveerd voor consoleprogramma's dan linux waardoor mijn programma in de problemen komt. Alhoewel ik het geheugen nogtans telkens weer vrijgeef. Ik sluit de files proper af, heb het programma zelfs gecompileerd onder de strengste voorwaarden (zonder memory leaks e.d.) dus ik zie niet in waarom windows meer geheugen zo nodig hebben dan linux voor mijn programma.
Ik wist het niet goed plaatsen want het kan uiteraard altijd een programmeerfout zijn (ik ben niet heilig natuurlijk) maar het kan natuurlijk ook iets eigen zijn aan fopen() en fclose() dat daar iets fout loopt waardoor windows foute adressen moet alloceren of wathever (bvb een fout bij de omzetting van die commando's naar machinetaal door de compiler, al lijkt me dat toch onwaarschijnlijk gezien het aantal jaren dat die compilers getest en gebruikt zijn).
Als compiler gebruik ik in windows Visual studio .NET 6.0 en op school de Visual Studio .NET 2003 en in linux gewoon cc
In windows had ik me mistypt en files van 2 bytes groot aangemaakt, nu was de file die ik wou splitten ongeveer 500kiB groot waardoor mijn programma 256 000 files wou aanmaken. Ik laat mijn pc wat rekenen en na een groot aantal minuten zie ik dat hij blijft steken bij 65 532 files. En windows (in mijn geval windows 2000) geeft een memory error. Na debugging constateer ik dat de stapelpointer (register esp) wijst naar adres 0x0000 0000 en een file wil schrijven op plaats 0x0000 0004
De esp wijst vervolgens naar het goede adres 0x0000 0004 maar op het moment dat hij daar enige bits wil schrijven (op dat adres) gaat het helemaal fout. Zoiets had ik uiteraard vermoed want mij lijkt het dat windows enige kritische informatie op de beginadressen van het geheugen heeft staan en dus niet wil dat die daar komen.
Allemaal goed en wel, maar ik wou dat toch even nader onderzoeken. Dus schreef ik gewoon een ander programma dat weer m.b.h.v. fopen() en file aanmaakt om te schrijven en dan het putc() daarin een (random) karakter steekt. Ik schrijf een kort lusje dat meer dan 65 532 laat schrijven en uiteraard sluit ik iedere file met fclose() na het schrijven van het karakter.
Ik compileer voer uit en pats na enkele minuten weer prijs, weer na 65 532 files, weer dezelfde foutmelding en weer betreffende dezelfde adressen.
Nu programmeer ik mooi volgens de ANSI-C standaard dus zeg ik bij mezelf waarom niet vlug even compileren en uitvoeren in linux (redhat 9.0 in mijn geval). Zo gezegd zo gedaan en tot mijn verbazing slaagt mijn programma er daar wel in om meer dan 65 532 files te schrijven (heb het voor 70 000 files getest).
Vervolgens test ik mijn splitter ook op files van een paar MiB's groot en ook hier slaagt hij erin te splitten in het correct aantal files.
Nu vraag ik mij toch een aantal dingen af, waarom zijn er problemen in windows en in linux niet? Kan het bijvoorbeeld zijn dat windows het geheugen slecht beheerd en dat door een bug bijvoorbeeld in windows een slecht stuk geheugen gealloceerd wordt door een willekeurig programma, waardoor windows uiteraard tegenstribbeld en een error geeft.
Of mijn ander vermoeden was dat windows minder geheugen reserveerd voor consoleprogramma's dan linux waardoor mijn programma in de problemen komt. Alhoewel ik het geheugen nogtans telkens weer vrijgeef. Ik sluit de files proper af, heb het programma zelfs gecompileerd onder de strengste voorwaarden (zonder memory leaks e.d.) dus ik zie niet in waarom windows meer geheugen zo nodig hebben dan linux voor mijn programma.
Ik wist het niet goed plaatsen want het kan uiteraard altijd een programmeerfout zijn (ik ben niet heilig natuurlijk) maar het kan natuurlijk ook iets eigen zijn aan fopen() en fclose() dat daar iets fout loopt waardoor windows foute adressen moet alloceren of wathever (bvb een fout bij de omzetting van die commando's naar machinetaal door de compiler, al lijkt me dat toch onwaarschijnlijk gezien het aantal jaren dat die compilers getest en gebruikt zijn).
Als compiler gebruik ik in windows Visual studio .NET 6.0 en op school de Visual Studio .NET 2003 en in linux gewoon cc