-1-es címről akar olvasni a Visual C++ 64 bites módban
2020-12-31T14:48:00+01:00
2021-06-23T15:33:25+02:00
2022-07-19T01:43:06+02:00
x00
Tisztelt tagság!

Visual C++ 2019 Community 16.8.3
64 bites Windows 10 Home 2004 teljesen befrissítve

Van egy sokat tudó AVL-fákat használó programom, mely 32 biten mindenhogy megy. 64 biten debug módban megy, release módban a -1-es címről (0xFFFF...) akar olvasni az AVL-fa rutin, 0xCCCC... címeket is látok ami definiálatlant jelent. Ha * helyett * __ptr32 van, akkor 32 bitesek a címek, ekkor debug módban se megy, még hamarabb jelentkezik a hiba, ekkor is -1-es címről akar olvasni. A fordítóprogramban lenne a hiba? Találtam már egyébként pár hibát a fordítóprogramban. Mivel hosszú, még nem készítettem el a legrövidebb, legegyszerűbb változatot amiben jelentkezik a hiba, pár 10 000 soros a forráskód. Egyébként natív unmanaged parancssoros program, a projekt fájl közel 20 éves, többször átkonvertálta, így nincs benne még MASM se, új projekt fájlt kellett létrehoznom hogy be tudjam állítani hogy a routine.asm MASM-mal fordul, nem marad ki. Azokat az AVL-rutinok nem használják.

Na úgy néz ki nemsokára lesz egy rövid program amiben jelentkezik a hiba. int-eket tartalmazó AVL-fába 0-t betettem, utána a -1-et már nem tudta betenni, 0xFFF....FFF3-as címről akar olvasni. Én továbbra is a fordítóprogramra gyanakszok. Ennél 32 bites címeket használok 64 bites programnál. Nyilván a linkelésnél beállítottam hogy csak az alsó 2 GB-ot használja. Bonyolultabbnál 64 bites címeknél is jelentkezik a hiba, de csak release módban. Ez a fura, hogy 32 bites programnál mindig megy, ezért gyanakszok fordítóprogram-hibára.
Mutasd a teljes hozzászólást!
Az lehet egyébként, hogy a __ptr32 és az & (address of) operátor nem úgy működnek együtt, mint ahogyan azt gondolnád: https://developercommunity.visualstudio.com/content/problem/620885/-..
Mutasd a teljes hozzászólást!

  • Forráskód híján elég nehéz megtippelni, mi lehet a hiba forrása. Mi lehet a különbség 64 és 32 bites mód között? Ekörül keresgélj: sizeof, size_t, ponter méretek, int_max, alignment és padding stb. Ha fordítóprogram hibára gyanakszol, akkor igazolhatod vagy cáfolatod a sejtésedet, ha másik fordítót is kipróbálsz. Ennek a legkisebb az esélye amúgy, de a te idődről van szó...
    Mutasd a teljes hozzászólást!
  • 64 bites mutatóknál is előjön a hiba, azt még nem tudom mi okozza.

    32 bites mutatóknál viszont a fordítóprogram a hibás. A **p már problémát okoz neki ha * __ptr32 * vagy * __ptr32 * __ptr32. p jó, *p is jó, **p az AVL-elem amit hasonlítani kell: *p a címe. Mire meghívja az operator <-et, már -D a cím: 0xFFFF...FFF3. Közvetlenül előtte kiírattam wcout-ra mindent: this, p, *p, előtte a gyökeret és a 2 részfa címét. Ez jó, és leáll, hogy erről a címről olvasott. Van call stack, autos, stb. A beszúró rutin keresi a helyét. Üres fába 0-t beszúr, utána bármit is szúrok be, mire meghívja az operator <-et a keresés, már megváltozik a gyökérelem címe: például *p
    = E7FF10, de az operator < már 0xFFF...FF3-at kap **p aktuális paraméterre, const AVL-elem &y formális paraméterre. Az autos méghibásabb, ott hiába 32 biten tároltam a címeket, ad hozzá felső 32 bitet is, de nem 0-t hanem 1, CCCCCCCC, stb. A CCCCCCCC a definiálatlan: gondolom az autos 64 bitet olvas ki a memóriából.

    Most kezdem azt a hibát keresni ami 64 bites mutatóknál is előjön.

    Másik fordítóm nincs, és tudtommal a * __ptr32-t csak a Visual C++ tudja, az is csak papíron mint kiderült.

    A másik is fordítóprogram hiba volt. Szép, hogy a Visual C++ nem képes AMD64-re fordítani. A beszúrásnál a gyökértől indulva keresi a helyét. Minden lépés előtt kiírattam p, *p, into-t. *into vagy **p már -1-es cím: into vagy *p = 1 a p = részben:

    telem **p = &root; while (*p) { it.put(*p); std::wcout << p << L' ' << *p << L' ' << into << std::endl; p = (*p)->avld.p + ! (*into < **p); }
    Az it tárolja az utat az egyensúlyozáshoz, into a beteendő AVL-elem. Itt is a p = -t mutatja a debugger, de az operator <-ig itt már el se jut: -1-es címről olvas itt is, vagyis into = -1 vagy *p = -1 lett, de az előttelevő sorban a képernyőre kiírásnál még 000000000109FD90 0000000001484C80 00000000014901C0. Itt is az autos, local, watch még hibásabb mint futás közben.

    Lehet hogy a project beállításai között valamit eltoltam? Nem állítgattam különösebbeket: LARGE_ADDRESS_AWARE ki, Unicode, fp:precise, #include esetén hol keresse a saját rutingyűjteményemet, induló aktuális könyvtár, stb.
    Mutasd a teljes hozzászólást!
  • Tényleg kéne valami kód, mert így csak tippelgetni lehet. Minden esetre ez alapján:

    Üres fába 0-t beszúr, utána bármit is szúrok be, mire meghívja az operator <-et a keresés, már megváltozik a gyökérelem címe

    nekem gyanús, hogy az operator< lesz a hunyó. Valahogy a hívó nem azt pakolja a veremre mint amit a hívott vár, és onnantól már simán lehet hogy felülfirkálja a hívó lokális változóit.

    De persze ez is csak egy tipp.
    Mutasd a teljes hozzászólást!
  • // AVL-elem template: only search key template<typename t, template<typename> class selem> class teavl: public selem<teavl<t, selem> > { public: friend void swap<>(teavl &, teavl &); template<typename tt> friend void swap(tt &, tt &); typedef t tkey; typedef t telem; tkey key; explicit teavl(const tkey &x): key(x) {} explicit teavl(tkey &&x): key((tkey &&) x) {} template<typename t> bool operator == (const t &other) const { return key == other; } template<typename t> bool operator != (const t &other) const { return key != other; } template<typename t> bool operator <= (const t &other) const { return key <= other; } template<typename t> bool operator >= (const t &other) const { return key >= other; } template<typename t> bool operator < (const t &other) const { return key < other; } template<typename t> bool operator > (const t &other) const { return key > other; } }; template<typename t, template<class> class s> bool operator == (const teavl<t, s> &x, const teavl<t, s> &y) { return x.key == y.key; } template<typename t, template<class> class s> bool operator != (const teavl<t, s> &x, const teavl<t, s> &y) { return x.key != y.key; } template<typename t, template<class> class s> bool operator <= (const teavl<t, s> &x, const teavl<t, s> &y) { return x.key <= y.key; } template<typename t, template<class> class s> bool operator >= (const teavl<t, s> &x, const teavl<t, s> &y) { return x.key >= y.key; } template<typename t, template<class> class s> bool operator < (const teavl<t, s> &x, const teavl<t, s> &y) { return x.key < y.key; } template<typename t, template<class> class s> bool operator > (const teavl<t, s> &x, const teavl<t, s> &y) { return x.key > y.key; }
    Tehát 32 bites mutatók 64 bites programnál: a legutolsó operator <-nél volt hogy y címe -1, és onnan akar kiolvasni. telem = int volt a tesztelésnél, selem = avle: olyan AVL-elem CRTP-ősosztály, melynek nincs felfele mutatója, nincs a fában levő elemek száma, és 1 fa csak 1-szer lehet részfa: több AVL-fának nem lehet közös részfája. Azért van a selem, hogy ilyenek is lehessenek.

    Amikor a mutatók is 64 bitesek voltak: ekkor nem volt * helyett * __ptr32, akkor el se jutott az operator <-ig, hanem egyszerűen a p = sorban a beszúrásnál -1-es címről olvasott, holott közvetlenül előtte a wcout <<-ban még nem volt -1-es cím.
    Mutasd a teljes hozzászólást!
  • class elem { public: elem * __ptr32 (p[2]); int key; }; bool operator < (const elem &x, const elem &y) { return x.key < y.key; } elem * __ptr32 root = nullptr; void insert(elem *i) { i->p[1] = i->p[0] = nullptr; elem * __ptr32 * __ptr32 p = &root; while (*p) p = (*p)->p + ! (*i < **p); *p = i; } int wmain() { insert(new elem); insert(new elem); return 0; }
    Érdekes módon itt nem jön elő a hiba. Valami kell még hozzá hogy előjöjjön: a 2 mutatót tároló tömb legyen külön osztály ahogy nálam, vagy sablon legyen, esetleg csak CRTP-sablonnál jön elő. Mint látszik, a kódból használt részekhez még egyensúlyozás se kell, sőt, még a tárolt adatot se kell beállítani: az int-et. Lehet hogy az kell hozzá hogy a gyökér ne magában legyen, hanem legyen egy osztály, ami csak a gyökeret tárolja, és annak a metódusa az insert. A példakód a legegyszerűbb program lett volna amiben előjön, de ebben nem jött elő a hiba.
    Mutasd a teljes hozzászólást!
  • Azt sajnos nem tudom hogy lehetne visszatérni a Visual Studio korábbi változatához, úgyhogy megvárom a 16.8.4-et, aztán annál majd újra próbálkozok, hátha sikerül. Egyébként a számítógépet újraindítva is ugyanaz mindig. Több bites memóriahiba javítását is tudja a számítógépem, be is van kapcsolva. Próbáltam a Visual Studio-t újratelepíteni is: repair.
    Mutasd a teljes hozzászólást!
  • Ha kiszeded az összes __ptr32 -t, akkor jó lesz?
    Mutasd a teljes hozzászólást!
  • A példakód a legegyszerűbb program lett volna amiben előjön, de ebben nem jött elő a hiba.

    Tehát továbbra is csak ott tartunk, higy a 10000 sorban van valahol egy vagy több h8ba. Az irány jó azonban, le kell szűkíteni a kört, ahol keresni kell.
    Mutasd a teljes hozzászólást!
  • Nem lesz jó. De egyébként már írtam: az összes __ptr32 kiszedése az az amikor 64 bites módban 64 bites mutatók vannak. Erről írtam, hogy ennél is jelentkezik a hiba, ekkor van hogy az operator <-et meg se hívja. A programban * helyett pdef van, és van egy

    #define pdef * __ptr32

    az elején, ebből csináltam * // __ptr32-t. A kód maga ugyanaz mint a rövid program, de abban nem jelentkezik a hiba: ha sablonba teszem, stb. akkor persze hibás, hiszen nálam is hibás, és pont az a kód van benne. Az eredeti program részletei a korábbi hozzászólásaimban vannak. Röviden: a program hibával leáll, a debugger a p = -s sornál írja ki hogy a 0xFFFF... címről próbált olvasni, call stack-kel se lehet lejjebb menni a veremben: ez van legalul. Előtte meg wcout << p, *p, into volt, és akkor még jó volt. Ez bizony a fordítóprogram hibája már megint.
    Mutasd a teljes hozzászólást!
  • Az előző hozzászólásom végéből is az derül ki, hogy nem nálam van a hiba. Az a rövid program ugyanaz a kód. Ha a fordítóprogram jó, akkor neki mindegy, hogy a key mező típusa int, vagy sablonparaméter, melynek az aktuális értéke épp most int: mivel ez pont ugyanazt jelenti! Több 10 000 sor egyébként, és ha az AVL-fában 1 elem van, a következőt már nem tudja beszúrni: egyes típusoknál jelentkezik, másoknál meg nem. Ott a kód az eredetiből is, úgy ahogy van, sablonosan. Azért az árulkodó hogy a használat előtt közvetlenül még nem -1 a cím: ott a wcout << p, *p, into közvetlenül előtte, írtam az eredményét is. Azt se hagyjuk már ki, hogy ugyanaz a program 32 bitesen simán megy, release és debug módban is. sizeof, stb. meg nincs benne, int és cím közötti konvertálás se.
    Mutasd a teljes hozzászólást!
  • A root az nullptrt tart kezdetben.
    Aztán p-ben eltárolod root címét.

    p = (*p)->p + ! (*i < **p);

    (*p)->p értéke mi lesz ekkor szerinted?
    Ja, hogy bele sem megy a ciklusba.  :)
    Mutasd a teljes hozzászólást!
  • Szerintem csinálj egy mvce-t (How to create a Minimal, Reproducible Example - Help Center) de ne legyen benne se __ptr32, se template.
    Mutasd a teljes hozzászólást!
  • Az megvan, nem jelentkezik benne a hiba: ki kell törölni belőle a __ptr32-ket. A fordító rossz, valami zavarja: template, stb. Vagyis például ha c<int> helyett csinálok egy cint osztályt, már jól működik. Valami ilyesmi hibája lehet. Elég egyértelmű, hogy **p előtt kiíratom a képernyőre p, *p-t, 1-32 MB közötti cím, majd a debugger azt írja hogy a -D ... -1 közötti címről próbált olvasni. Ez csak a fordítóprogram hibája lehet. Megvárom a következő javító kiadást, addig maradok 32 biten.
    Mutasd a teljes hozzászólást!
  • Te vagy a hunyó! 

    Első kérdés: sizeof(int) 4 vagy 8?

    Tippem:
    A probléma a -1 esetében, hogy a 64 bites stack érték (pointer) felső része kerül egy 32 bites int változóba.
    Mutasd a teljes hozzászólást!
  • Nem, a fordítóprogram. Az int 4 byte-os. A -1-et már nem írja ki a program, azt már a debugger írja ki. Leegyszerűsítve:

    cout << p << ' ' << *p << endl;
    **p;

    2 darab 1-32 MB közötti, 64 bites címet ír ki: 16 számjegy.
    Utána a következő sor hibával leáll, és azt mondja hogy a 0xFFFFFFFFFFFFFFFy címről próbált olvasni, de az a memóriaterület nem érhető el, így nem sikerült neki. y többféle lehet, 3 is szokott lenni. Ez csak a fordítóprogram hibája lehet.
    Mutasd a teljes hozzászólást!
  • Na közben rájöttem hogy más a hiba. Szóval azt észrevettem, hogy a watch, autos, locals a  változókban tárolt címeknek tök hülyeségeket ír ki, úgy rossz ahogy van. Ugyanígy, az is hibás, hogy azt írja ki hogy a -D - -1 közötti címről olvasott: elérhetetlen memóriaterületről olvasott, de nem arról a címről amit kiír, hanem arról amit a képernyőre írt ki a wcout <<. Vagyis a cím nem -1, -D, stb. csak a debugger hibás, és azt állítja. A root tartalmazza az AVL-fa gyökérelemének címét. Ez mutat olyan területre ami nem olvasható. Csak 64 bit release módban, és csak egyes elemtípusoknál: más típusnál egész nagy fáknál is ment, még mielőtt kiakadt volna. Na akkor megnézem hol akad el, előtte kiíratom a gyökeret, tartalmát. Megnézem, hogy 1 elem beszúrása után gyökér a beszúrt elem címe-e, mezői olvashatók-e. De szerintem az lesz, vagyis nem csak a debugger, hanem a fordító is hibás lesz.

    Igen, tényleg a fordítóprogram hibás. Beszúrás előtt kiírattam a gyökér és a beszúrandó elem címét a képernyőre. Valóban üres fánál 0 gyökér. Utána a gyökérelem 2 mutatóját: 0 valóban, tehát ez a terület igenis olvasható. A rendezési kulcsot is kiírta, tehát az is olvasható. A következő elem beszúrása előtt is kiírattam a gyökér és beszúrandó elem címét. A gyökér az előzőleg beszúrt elem. Itt már a beszúrás előtt írattam ki a beszúrandó elem 2 mutatóját és a keresési kulcsot, mivel a beszúrás utáni kiírások már nem futnak le, mert kiakad előttük a program. Tényleg 0, és kiírta, tehát ez a memóriaterület olvasható. A ciklusban a részfára lépés előtt most is kiírattam: p, *p, into, vagyis a gyökér címét tartalmazó változó címét, a gyökér címét, és a beszúrandó elem címét. Ezek is jók: pont az aminek lennie kell: az előzőleg beszúrt és a most beszúrandó elem címe. És itt már nem tudta olvasni azt a memóriaterületet amit a beszúrási rutin meghívása előtt még tudott olvasni.
    Mutasd a teljes hozzászólást!
  • Annak a kódnak, amely 32 bites változatban lefordul és hibátlanul fut, a 64 bites változatban is hibátlanul fordulni és futnia kell?

    Ha tippelnem kéne, akkor a két környezetben az eltérő pointer méretek miatti memória felülírás okozza a gondot.

    a beszúrás utáni kiírások már nem futnak le

    Akkor érdemes lenne bele debuggolnod a generált kódba, és megnézned, hogy a beszúráskor a mutató írása jó címre és mérettel történik-e?

    a pointerek használata

    ami közvetlenül érinthet az a 3. bekezdés
    Mutasd a teljes hozzászólást!
  • Jelenleg nincsenek keverve a típusok: 64 bitesre fordításnál 64 bites a mutató: * van csak, nincs __ptr32. És természetesen semmilyen típuskonverzió sincs: se egészre, se másra, egészből másra se! A mezőtípus, lokális változók típusa, stb. egyszerűen *, nem int! Mivel közvetlenül a hiba előtt kiírattam a képernyőre, csak a fordítóprogram hibája lehet: lefut a kiírás, majd kiakad a program.
    Mutasd a teljes hozzászólást!
  • warning C4244: 'initializing': conversion from 'elem * __ptr32*' to 'elem * __ptr32* __ptr32', possible loss of data warning C4244: '=': conversion from 'elem *' to 'elem * __ptr32', possible loss of data11 warning C4244: '=': conversion from 'elem * __ptr32*' to 'elem * __ptr32* __ptr32', possible loss of data
    Teli van warningagl a példa kódod, szerintem gondold át az összes lépést, ahol 64 bites mutatót csonkolsz 32 bitesre, mert ezeken a helyeken, ahol a felső 32 bitben nem csupa nulla volt, ott azonnal hibát fogsz kapni, és az nem a fordító hibája hanem a tied.

    Tudnál egy olyan változatot küldeni, ahol nincs warning sem és templatek is vannak  (mert szerinted ott romlik el valami), és ahol tényleg olvasási hibát kapunk futtatáskor?

    Mert az a kód, amit küldtél, az a while(*p) sorban meghal, még bele sem megy a ciklus törzsébe, nem hogy wcouttal bármit is kiiratna.
    Mutasd a teljes hozzászólást!
  • Jelenleg nincsenek keverve a típusok: 64 bitesre fordításnál 64 bites a mutató: * van csak, nincs __ptr32. És természetesen semmilyen típuskonverzió sincs

    Dehogy is nincsenek, pont azért kapod a warningokat, amit beidéztem...
    Mutasd a teljes hozzászólást!
  • Az lehet egyébként, hogy a __ptr32 és az & (address of) operátor nem úgy működnek együtt, mint ahogyan azt gondolnád: https://developercommunity.visualstudio.com/content/problem/620885/-..
    Mutasd a teljes hozzászólást!
  • Írtam, hogy ha nincs template, stb. akkor nem jelentkezik a hiba! Amiben jelentkezik, abban nincs __ptr32, és csak 1 típusnál jelentkezik a hiba! Írtam azt is hogy beállítottam linkelésnél hogy csak az alsó 2 GB-ot használja. Azt is írtam hogy a képernyőre kiírt címek 1-32 MB közöttiek. Több 10 000 sor sablonnal együtt, le lehetne rövidíteni hogy csak a használtakat, de minek? Úgyis több 100 sor, és úgyis a fordítóprogram hibája, felesleges vele foglalkozni.
    Mutasd a teljes hozzászólást!
  • Egyébként mi a szándékod ezzel az egész 32 bites pointer trükközéssel? 64 bites módban a mutatók kétszer annyi memóriát foglalnak el, ezzel akarsz spórolni?

    Az nem gond, hogy a "new elem" hivások 64 bites memória címeket adnak vissza és ha ezeket bármikor átalakítod 32 bitesre, akkor elveszted a felső biteket? Nekem a példa kódodban az első elem már a 0x000001ffc53b19a0 címen kerül lefoglalásra és ez sehogy sem fér el 32 biten.

    Ha tényleg memóriával akasz spórolni, akkor célszerűbb pointerek helyett indexeket használni és nem new-t hanem saját memória poolt használni az elem típushoz.
    Mutasd a teljes hozzászólást!
  • Spórolás lenne, mert tiszta AVL-fa az egész.

    Mert az a kód, amit küldtél, az a while(*p) sorban meghal, még bele sem megy a ciklus törzsébe, nem hogy wcouttal bármit is kiiratna. 

    Szedd ki a __ptr32-t, vagy a linkernél kapcsold ki a LARGE_ADDRESS_AWARE-t. És nem ez írja ki, hanem a nagy eredeti program a címeket. Na mingyár összeszedem neked amit használok belőle. És a new nekem az alsó 2 GB-ba adja!
    Mutasd a teljes hozzászólást!
  • Esetleg lehetne olyan, hogy egy darab, önmagában fordítható, tesztelhető source, amit mutatja a problémát, de nincs benne semmi, ami nem esszenciális a hiba bemutatásához?
    Mutasd a teljes hozzászólást!
  • A __ptr32 továbbra is problémás, lásd a mellékelt screenshotot. Annyival bővítettem a példádat, hogy az elemhez létrehoztam egy konstruktort, ami kitölti a key-t és a ptr értékeket. Így a mainban van egy insert(new elem(1)) és 2-vel ugyanez.

    Ez előhozta az egyik hibádat, ti. az operator< referenciákat a fordító mutatókra fordítja, de a jelek szerint fixen 64 bites címet vár a referencia esetén és nem 32 bitest, így a key=1 érték "hozzácsapódik" az elem címéhez. (Itt már kikapcsoltam a large addresseket és nálam is 2G alatt generált a new új címeket) tehát az 100c50fb0 címről akar olvasni azért mert key=00000001 volt.
    Mutasd a teljes hozzászólást!
    Csatolt állomány
  • És igen, tényleg úgy néz ki, a debugger nem támogatja a 32 bites pointereket, mert a root-ot megvizsgálva tényleg rosszul mutatja az értékeket, de ha írok egy sima rekurzív print rutint a fához, akkor az jól kíírja a beszúrt 1 és 2 értékeket.

    Persze ez még továbbra sem jelenti azt, hogy fordító hibát találtál.
    Mutasd a teljes hozzászólást!
  • Persze ez még továbbra sem jelenti azt, hogy fordító hibát találtál.

    Dehogynem!

    int a;
    int * __ptr32 p = &a;
    int b = 1;

    void f(const int &x) { x; }

    f(*i)

    Ebben az egyszerű példában itt a vermen van, így nem jön elő, de struct-ban, tömbben előjöhet.
    Amennyiben a cím felső 32 bitje f hívásánál nem 0, hanem 1, a b miatt, akkor az hiba! Egyszerűen hibás a *i kifejezés, ha referenciának adjuk át, és i típusa * __ptr32. Ez bizony a fordítóprogram hibája!

    Az is hiba, hogy ha MASM-mal fordított, külön fordítási egységben levő, extern "C"-vel deklarált rutinban van a hiba, akkor utána még több hívási szintet ugrik, mire a call stack megtalálja. Na jó, ez a release módban levő optimalizáció miatt van, de felfoghatatlan így is, hogy akkor debug módban ugyanaz a rutin miért jó? Ennél nem volt __ptr32, tehát 64 bitesek voltak a mutatók, és érdekes módon debug módban nem jelentkezett a hiba. Szóval a keresési kulcs unicode szöveg volt, és érdekes módon release módban valahogy rossz címről olvasott, debug módban meg jó címről, ugyanaz az általam írt assembly rutin! 64 biten tárolt mutatóknál! Na mindegy, most C++ ciklussal hasonlítom össze a 2 szöveget, így már 64 bites mutatóknál jó, de 32 biteseknél előjön a hiba amit írtál. Köszi a segítséget amúgy.

    Amit linkeltél hibabejelentést, ott azt írták hogy folyamatban van a javítása, szóval remélem hamar kijön a 16.8.4 és annál már jó lesz. A másik hiba tényleg nálam volt, biztos más a cím debug és release módban. Köszönöm a segítséget! Mivel a teljes adatszerkezet szinte tisztán mutató: AVL-fa, és a tárolt hasznos adat is sokszor mutató, megvárom a hibajavítást. 64 biten szinte minden méret a duplájára nőne, így belassulna, bár lehet, hogy a 7 regiszter helyett 15 behozná (RSP nélkül).
    Mutasd a teljes hozzászólást!
  • Namostan az ok, hogy nincs meg a forráskód gomb, de az 'i' változó az ugye 'p' akart lenni?

    És miért a fordító hibája az, hogy te szándékosan rossz kódot alkotsz? Pontosabban mondva, a te felelősséged, hogy csak olyan adatokat címezz ezzel a pointerrel, amik a 64-bites címtartomány legalján (vagy legtetején(*)) helyezkednek el.

    A másik problémád oka inicializálatlan változó lehetett, de ezt mindenképpen külön topikban kellene tárgyalni.

    (*) attól függ, hogy a felső 32 bitet fixen nullára veszi-e, vagy előjelkiterjesztés végez (én az utóbbira tippelek)

    Szerk: lehet, hogy a te panaszod éppen az, hogy felfedezted, hogy a 32-bites cím 'kiterjesztés' az előjelesen történik? Mert akkor a jó hír az, hogy ez nem hiba.
    Mutasd a teljes hozzászólást!
    Csatolt állomány
abcd