Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

[Win32] Hoe werkt een pointer naar lange arrays?

Pagina: 1
Acties:

  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 23:20
Ik wil een DLL maken die wat array's gaat bewerken. Deze array's kunnen aardig lang zijn en daar moet je denken aan groottes van ruim 10 miljoen posities en veel groter.

Bij een functie in de DLL geef ik dan de pointer naar de array en de lengte van de array mee.

Het is dus zo dat als ik een array heb van 10 miljoen posities van het type integer (32 bit dus), het pointeradres moet gebruiken om positie 0 uit te lezen. Voor locatie 1 gebruik ik het pointeradres + 4. Voor locatie 2 het adres + 8 en zo verder.

Nu kan ik mij goed voorstellen dat bij grote array's, die dus veel geheugen nodig hebben, geen aaneengesloten stuk geheugen gereserveerd kan worden.

Hoe gaat Windows hier mee om? En moet ik er rekening mee houden dat een array op een ander adres verder gaat?

Met het zoeken op internet heb ik hier geen antwoord op gevonden. De meeste resultaten gaan over basis van een array meegeven en pointers zelf. Ook de array's zijn daar ook niet zo groot. :)

Ik heb het vermoeden dat Windows een virtuele geheugenbank heeft die ergens diep in Windows naar het echte geheugen verwijst. De pointer die programmeurs gebruiken zouden dan verwijzen naar de virtuele geheugenbank.
Over deze theorie heb ik niets gevonden die het bovenstaande kan bevestigen of ontkennen.

Ik wil uiteindelijk dus weten of ik arraypositie 9.999.999 gewoon kan uitlezen op pointeradres + 9.999.999 * 4 en of Windows dat doet op de manier die ik heb beschreven of juist totaal anders.

Speel ook Balls Connect en Repeat


  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Hangt heel erg van je functies af. Gebruik je standaard functies dan heb je er in principe niets mee te maken en presenteert windows gewoon een aaneengesloten stuk geheugen aan jouw prog. Hoe gefragmenteerd / gebroken het in de praktijk ook is, al staat 25% weg geswapt, jij ziet gewoon 1 aaneengesloten stuk geheugen

Gebruik je niet-standaard functies ( vanwege performance bijv. ) dan is het heel erg afhankelijk van de gebruikte lib.

  • CoolGamer
  • Registratie: Mei 2005
  • Laatst online: 16-11 22:47

CoolGamer

What is it? Dragons?

Applicaties krijgen een "Virtual Address Space" die maar bij 1 applicatie hoort. Daaruit kan je niet afleiden waar het in de werkelijkheid in het geheugen staat, ook niet of het als 1 stuk achter elkaar staat. Voor je applicatie zal het 1 blok lijken, waarbij alle data netjes achter elkaar staat, dus je kan gewoon gebruik maken van array's.

Hier kan je er wat meer over vinden: http://msdn.microsoft.com/en-us/library/aa366912(VS.85).aspx

[ Voor 12% gewijzigd door CoolGamer op 25-07-2008 23:43 ]

¸.·´¯`·.¸.·´¯`·.¸><(((º>¸.·´¯`·.¸><(((º>¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸<º)))><¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸


  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 23:20
Bedankt. Mijn vermoedens kloppen dus. :)
Ik kan dus rustig met pointers doorwerken, en het scheelt een hoop extra uitzoekwerk. :)

Speel ook Balls Connect en Repeat


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 17-11 16:12

Robtimus

me Robtimus no like you

Onbekend schreef op vrijdag 25 juli 2008 @ 19:31:
Het is dus zo dat als ik een array heb van 10 miljoen posities van het type integer (32 bit dus), het pointeradres moet gebruiken om positie 0 uit te lezen. Voor locatie 1 gebruik ik het pointeradres + 4. Voor locatie 2 het adres + 8 en zo verder.
Kun je niet beter gewoon steeds de pointer verhogen dmv ++? Ik meen me te herinneren dat dat in C en/of C++ automatisch de sizeof gebruikt om de volgende plek te vinden.

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

int main()
{
    int array[10];
    int i;
    int *ptr;

    for (i = 0; i < 10; i++)
    {
        array[i] = i;
    }
    ptr = array;
    for (i = 0; i < 10; i++, ptr++)
    {
        printf("array[%d] == %d\n", i, *ptr);
    }
}

Output:
code:
1
2
3
4
5
6
7
8
9
10
array[0] == 0
array[1] == 1
array[2] == 2
array[3] == 3
array[4] == 4
array[5] == 5
array[6] == 6
array[7] == 7
array[8] == 8
array[9] == 9

Vervang ik int door long int in zowel de array declaratie als de pointer declaratie dan krijg ik dezelfde output.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 23:20
Klopt. Die functie wil ik ook gaan gebruiken. Maar om mijn vraag zo duidelijk mogelijk uit te leggen had ik eventjes het getal 4 gebruikt i.p.v. SizeOf.
Het is straks ook de bedoeling om met een array van 8bit en van 16bit getallen te gaan werken.

Speel ook Balls Connect en Repeat


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:04

.oisyn

Moderator Devschuur®

Demotivational Speaker

Een native array is sowieso standaard consecutive. Als dat niet zo is, dan is het geen array. Als jouw functie dus wordt aangeroepen met een pointer naar het eerste element en het aantal elementen, dan staan de elementen gewoon achter elkaar.

Als je geheugen voor een array wilt alloceren die te groot is om nog in een vrij stuk in de virtual address space te passen, dan mislukt de allocatie. Als je met arrays van een dergelijke grote wilt werken (zeg > 100.000.000 elementen), dan is het sowieso handiger om ze op te delen in stukjes en die stukjes afzonderlijk te alloceren. Natuurlijk heb je dan ook weer een array nodig om de pointers naar die losse stukjes in op te slaan - in feite wordt het dan een 2d array.

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
static const unsigned
    cChunkBits = 20,               // 20 bits == 1M elementen
    cChunkSize = 1 << cChunkBits,
    cChunkMask = cChunkSize - 1;

int ** allocInts(unsigned numElements)
{
    unsigned numPages = (numElements + cChunkSize - 1) >> cChunkBits;
    int ** ptr = new int*[numPages];

    // eerst N-1 volledige pages
    for (unsigned i = 0; i < numPages - 1; i++)
        ptr[i] = new int[cChunkSize];

    // en de laatste page
    ptr[numPages-1] = new int[numElements & cChunkMask];
    return ptr;
}

int & getInt(int ** elements, unsigned pos)
{
    unsigned page = pos >> cChunkBits;
    unsigned offset = pos & cChunkMask;
    return elements[page][offset];
}

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1