[C/C++] Pointers naar verplaatst geheugenblok bijwerken

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
Dat wil dus niet echt. Eerst maar eens de code:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
void [...]::setCacheSize(void* cache,int newsize) {

[...]
        if(numobjects > 0)
            Debug.msgbox(objects[numobjects-1].diffusetex->fullpath,"Test");

        // Store old position
        size_t oldposition = (size_t)&textures[0];
        
        // Resize
        texturecachesize = newsize;
        textures = (TEXTURE*)realloc(textures,texturecachesize*sizeof(TEXTURE));
        
        // Determine move in memory
        ssize_t offset = (size_t)&textures[0] - oldposition;

        // Fix references
        for(unsigned int i = 0;i < numobjects;i++) {
            objects[i].diffusetex  = (TEXTURE*)((char*)objects[i].diffusetex  + offset);
            objects[i].speculartex = (TEXTURE*)((char*)objects[i].speculartex + offset);
            objects[i].normaltex   = (TEXTURE*)((char*)objects[i].normaltex   + offset);
            objects[i].parallaxtex = (TEXTURE*)((char*)objects[i].parallaxtex + offset);
            objects[i].ambienttex  = (TEXTURE*)((char*)objects[i].ambienttex  + offset);
        }

        if(numobjects > 0)
            Debug.msgbox(objects[numobjects-1].diffusetex->fullpath,"Test");
[...]

}
typedef struct {
    LPDIRECT3DTEXTURE9 pointer;
    char fullpath[MAX_PATH];
} TEXTURE;
typedef struct {

[...]

    TEXTURE *diffusetex,*speculartex,*normaltex,*parallaxtex,*ambienttex;

[...]

} OBJECT;


De comments spreken hopelijk voor zich, want er gebeurt niet bijster veel.

Dit gaat soms goed en soms niet. Het schrijven naar de pointers gaat allemaal goed, maar op het moment dat de LPDIRECT3DTEXTURE9 geSet wordt, crasht de boel. Ook zijn sommige fullpath's leeg (of er staat een \0 op de verkeerde plek).

Wat er gecontroleerd is:
  • Er zijn geen threads die tegelijk de data gebruiken.
  • Op het moment dat er geschoven wordt (bij een *re*alloc dus) gaat het mis.
Dat laatste gerommel binnen die loop is overigens nodig om een pointer met 1-byte stappen te kunnen veranderen. Ik kan zo snel niet op een mooiere aanpak komen eigenlijk.

En dit is wat de debugconsole rapporteert:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[2268] Direct3D9: (INFO) :Direct3D9 Debug Runtime selected.

[... Standaard opstarttroep ...]

[2268] Invalid parameter passed to C runtime function.
[2268] Invalid parameter passed to C runtime function.
[2268] Invalid parameter passed to C runtime function.
[2268] Invalid parameter passed to C runtime function.
[2268] Invalid parameter passed to C runtime function.
[2268] Invalid parameter passed to C runtime function.
[2268] Invalid parameter passed to C runtime function.
[2268] Invalid parameter passed to C runtime function.
[2268] Invalid parameter passed to C runtime function.
[2268] Invalid parameter passed to C runtime function.
[2268] Invalid parameter passed to C runtime function.
[2268] Invalid parameter passed to C runtime function.
[2268] Invalid parameter passed to C runtime function.
[2268] Error - 
[2268] RtlWerpReportException failed with status code :-1073741823. Will try to launch the process directly


Die 'Invalid parameter passed to C runtime function.'-meldingen krijg ik altijd, ook als ik niet die functie gebruik, maar Google en met de hand debuggen (commenten en msgbox enzo) bieden helaas geen oplossing voor die vage melding: grote kans dat er intern in D3D9 wat mis gaat. Kan toch gerelateerd zijn. En die laatste is helaas een standaardfoutmelding waar ik niks wijzer van word (de tweede bit op 1 geloof ik).

Ziet iemand wat er fout gaat?

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Orwell schreef op zondag 22 januari 2012 @ 00:14:
Dit gaat soms goed en soms niet.
size_t is unsigned en je hebt soms een negatief verschil? realloc heeft soms te weinig geheugen en je hebt zojuist je pointer foutief overschreven?

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Radiant
  • Registratie: Juli 2003
  • Niet online

Radiant

Certified MS Bob Administrator

Als je toch alles vanuit "objects" doet en daar pointers hebt; waarom maak je bij je cache geen gebruik van een linked list? Scheelt in reallocaten..

Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
pedorus schreef op zondag 22 januari 2012 @ 02:00:
[...]

size_t is unsigned en je hebt soms een negatief verschil? realloc heeft soms te weinig geheugen en je hebt zojuist je pointer foutief overschreven?
De offset is wel signed. ;)

Dat zou wel goed moeten gaan.
Radiant schreef op zondag 22 januari 2012 @ 09:01:
Als je toch alles vanuit "objects" doet en daar pointers hebt; waarom maak je bij je cache geen gebruik van een linked list? Scheelt in reallocaten..
Ik doe hier en daar wat random access in die objectberg, dus ik houd het liever bij een mooie lijst. Aan de andere kant kan ik gewoon wat adressen opslaan van de plekken waar dat gebeurt. Hmm, ik bewaar het idee wel als alternatief.

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Volgens mij mag je dit helemaal niet zo doen; geen enkele garantie dat het goed gaat. Hij zou je pointers bv naar een ander segment kunnen mappen.

Ik kreeg die "Invalid parameter passed to C runtime function." laatst trouwens toen ik met malloc een stuk ter grootte van 0 bytes vroeg.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:51
Het lijkt me sterk dat dit het probleem is, maar het resultaat op regel 15 is in principe undefined als het nieuwe adres kleiner is dan het oude adres, want die expressie is gewoon unsigned, en de conversie naar een signed type is dan ongedefinieerd. Beter gebruik je overal ssize_t's.

Concreet weet ik ook niet precies wat er mis gaat. Kun je die waarde van offset eens debug-printen?

[ Voor 14% gewijzigd door Soultaker op 22-01-2012 13:34 ]


Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
Zoijar schreef op zondag 22 januari 2012 @ 13:09:
... Hij zou je pointers bv naar een ander segment kunnen mappen.
Wat bedoel je daar precies mee? Die pointers verwijzen niet naar VRAM of wat voor ander segment dan ook?
Ik kreeg die "Invalid parameter passed to C runtime function." laatst trouwens toen ik met malloc een stuk ter grootte van 0 bytes vroeg.
Zal er is naar kijken, maar ik denk niet dat het in dit geval daardoor komt.
Soultaker schreef op zondag 22 januari 2012 @ 13:33:
Het lijkt me sterk dat dit het probleem is, maar het resultaat op regel 15 is in principe undefined als het nieuwe adres kleiner is dan het oude adres, want die expressie is gewoon unsigned, en de conversie naar een signed type is dan ongedefinieerd. Beter gebruik je overal ssize_t's.
Geprobeerd. Werkt helaas niet. :/
Concreet weet ik ook niet precies wat er mis gaat. Kun je die waarde van offset eens debug-printen?
Als eerste alloct (realloc aapt malloc na) hij met een offset van 3186592. Dan komen er reallocs met als offset 85184, 422000, en als laatst altijd eentje van 0, wat misschien een beetje apart is. Het is overigens hiermee getoond:

C++:
1
2
3
4
void ClassDebug::msgbox(__int64 var,const char *caption) {
    sprintf(buffer,"%I64d",var);
    MessageBox(hwnd,buffer,caption,MB_ICONINFORMATION);
}


Oh, als ik wat anders laad en hercompileer krijg ik een ander standaardpatroon. Lange leve caching. Die 0 was dus puur toeval. Kon blijkbaar nog wat bij aan het eind. :P

[ Voor 53% gewijzigd door Orwell op 22-01-2012 13:52 ]


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Orwell schreef op zondag 22 januari 2012 @ 13:35:
Wat bedoel je daar precies mee? Die pointers verwijzen niet naar VRAM of wat voor ander segment dan ook?
Nou, beetje flauw misschien en ik denk niet dat dat je probleem is, maar dit zou bijvoorbeeld niet noodzakelijk werken op een 80386 in real-mode.

Verder zou ik het nooit zo implementeren... std::vector<TEXTURE> en in je objects een integer index in die vector is bijvoorbeeld al veel makkelijker. Je gebruikt een member functie, dus je gebruikt C++. Waarom een char path[MAX_PATH] en geen std::string? Al die pointer dingen kosten zo veel tijd en gaan zo vaak fout. Eerlijk gezegd gebruik ik zelden nog ruwe pointers in C++. Alles wat ik moet alloceren gaat via een std::shared_ptr, elke array een std::vector oid.

[ Voor 23% gewijzigd door Zoijar op 22-01-2012 15:11 ]


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

als ik X set, crash the boel

99% kans AV, ie, je bent aan het schrijven naar een buffer die je niet "hebt", dus je doet iets fout bij een alloc of een pointer remap.

pointers "remappen" klinkt leuk, maar heb je al gewoon indices overwogen? en een std::vector ipv realloc?

[ Voor 11% gewijzigd door MLM op 22-01-2012 15:24 ]

-niks-


Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
Het hele projectje is inderdaad een beetje een verzameling van C en C++ geworden. Moet er toch is wat aan gaan doen. :P

En eh, ja, indices, waarom vergeet ik zoiets. 8)7

Hmm, handig. En raad eens, het werkt nog ook! Zelfs met minder regels. Een stuk of twee in plaats van 20.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:51
Jammer dat we nu niet weten waarom het niet werkte... het was verre van elegant maar in principe had het gewoon moeten kunnen werken naar mijn idee.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Je blijft het je toch afvragen inderdaad, jammer dat het wat lastig te reproduceren is. Ik heb nog wel een vrij theoretische mogelijkheid, ook omdat alle offsets positief waren. ssize_t is niet helemaal correct.
The type ssize_t is capable of storing values at least in the range [-1, SSIZE_MAX]
http://stackoverflow.com/...een-ssize-t-and-ptrdiff-t

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
Je wordt dat uitzoeken wel zat als je er een tijdje naar zit te staren. :P

Maar eh, sja, ik weet het ook niet. En ehm, ik kwam zo af en toe ook wel een paar negatieve offsets tegen. Ze waren zeldzaam, maar ze waren er wel!

Heb m'n IDE (met TDM-GCC x64) even niet bij me, maar ik geloof dat ssize_t werd gedefinieerd als een signed __int64. Die zou dus perfect tot de helft van dat megalimiet 64bit moeten kunnen opslaan, positief en negatief.
Pagina: 1