Results 1 to 11 of 11

Thread: Free Pascal: Informatie over dynamische arrays

  1. #1

    Free Pascal: Informatie over dynamische arrays

    Hoi,
    Ik ben gisteren even bezig geweest met Free Pascal, en wilde daar wat dingen met dynamische arrays doen. Ik kwam tot de conclusie dat dit wel wat moeilijker was dan in Delphi: Geen SetLength, en je kunt ook niet 'Variable: array of TIets' gebruiken.

    Ik zal dus met pointers moeten gaan werken, GetMem en FreeMem en voor het resizen waarschijnlijk ReAllocateMem.

    Ik maak een record aan, hoe maak ik dan een dynamische array van records ? In een voorbeeldje stond ergens, dat je een statische array maakt met dus als grootte de lengte die de array maximaal kan gaan worden in je programma.

    Wat ik wil maken, zou er in Delphi ongeveer zo uitzien:
    Code:
    Type TPersoon = Record
      Naam: String;
      LeefTijd: Byte;
      Telefoon: Array of String[11]; // Bijv. 1234-567890
    end;
    
    ..
    
    var
      Personen: Array of TPersoon;
    Dan op de Pascal manier, maar wel in Delphi geschreven (zonder Telefoon in het record):

    Code:
    Type TPersoon = Record
      Naam: String;
      LeefTijd: Byte;
    end;
    
    Type Personen = Array [0..9] Of TPersoon;
    Type PPersonen = ^Personen;
    
    var
      PersonenLijst: PPersonen;
    
      ShowMessage(IntToStr( SizeOf(PersonenLijst^))); // geeft 80 terug
      GetMem(PersonenLijst, 3*SizeOf( TPersoon ));
      ShowMessage(IntToStr( SizeOf(PersonenLijst^))); // 80
    
      // Ik ging er dus vanuit dat de showmessages de lengte van de gereserveerde ruimte zouden teruggeven, dat doen ze schijnbaar niet.
    
      PersonenLijst^[0].Naam := 'Pieter';
      
      PersonenLijst^[6].Naam := 'Pieter'; // Dit leidt tot een AV...
      PersonenLijst^[6].LeefTijd := 46; // Dit kan raar genoeg wel, als ik voorgaande regel natuurlijk eerst weghaal. Waarom kan dit wel, en voorgaande niet ? Bij beiden ken ik waarden toe aan een gedeelte wat ik nog niet heb gereserveerd.
    
      FreeMem(PersonenLijst, 3*SizeOf( TPersoon ));
    Ik kan het natuurlijk ook verkeerd doen, maar de manier waarop ik het hier heb toegepast stond op verschillende sites.

    Ik moet de array ook nog kunnen resizen, dat de gegevens die er in staan behouden blijven.
    En als dat eenmaal lukt, ook de 'lijst' met telefoonnummers erin, zoals bij het Delphi voorbeeld stond.

    Wie kan mij helpen met wat informatie hoe ik wel zoiets kan doen? Alleen de manier waarop, het programma maken doe ik zelf graag .

    Groeten, Pieter

  2. #2
    • Titel aangepast, was "Informatie over dynamische arrays", zie 3 seconden
    Marcel

  3. #3
    SillyMember
    Join Date
    May 2003
    Location
    Gent
    Posts
    7,725
    Volgens de docs ondersteunt FPC dynamische arrays sinds versie 1.1
    All methodologies are based on fear. -- Kent Beck.

  4. #4
    SillyMember
    Join Date
    May 2003
    Location
    Gent
    Posts
    7,725
    Ook:
    Code:
      Telefoon: Array of String[11]; // Bijv. 1234-567890
    Telefoon is nu een dynamische array.
    Ik vermoed dat je bedoelt ShortString:
    Code:
      Telefoon: string[11]; // Bijv. 1234-567890
    All methodologies are based on fear. -- Kent Beck.

  5. #5
    En als ik nou een hele oude versie had ...
    Nee maar ik wil het graag met GetMem en FreeMem enz. doen, steek ik er ook weer meer van op.

    [Edit]
    Niet helemaal duidelijk verteld, sorry: het is een lijst met telefoonnummers (mobiel, thuis enz).

  6. #6
    SizeOf geeft de grote van het type var terug dat je er aan meegeeft. Dit is compiler magic. De compiler weet niet beter of het array is 10 groot en TPersoon bezet 8 bytes (4 voor de string wat een pointer is, plus 1 voor een byte en dan gealigned op 4 bytes is 8). Dat jij runtime meer ruimte reserveerd veranderd daar niets aan. Alleen de memory manager weet nog hoe groot de ruimte is die je er voor gereserveerd hebt. Beter is om dat zelf met een aparte variable bij te houden.

    Dat het fout gaat bij het toekennen van een string buiten de array bounds, maar het wel goed gaat bij een integer komt omdat een string meer is. Het is een hele structuur met de lengte van de string en een reference count etc. De integer zet gewoon direct ergens in het geheugen te schrijven waar het niet hoort, maar de string zal een bewerking proberen uit te voeren op random geheugen.
    We adore chaos because we like to restore order - M.C. Escher

  7. #7
    Oke, dankjewel voor de informatie, daar heb ik wat aan =).
    De methode die ik gebruik is dus goed? En dan kan ik waarschijnlijk ook ReAllocMem gebruiken om de array weer te resizen.

    Is er nog een andere methode om een dynamische array the realiseren op ongeveer bovenstaande manier ?

  8. #8
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Code:
     reallocmem(PersonenLijst, 3*SizeOf( TPersoon ));
    Overigens kan je in FPC ook niet-pchar pointers overindexen, in de ObjFPC mode. Dat is een extensie op delphi:

    Code:
    {$mode objfpc}
    
    Type TPersoon = Record
      Naam: String;
      LeefTijd: Byte;
    end;
    
     PPersonen = ^TPersoon;
    
    var
      PersonenLijst: PPersonen;
    
    begin
      getmem(personenlijst,sizeof(tpersoon)*5);
      personenlijst[2].naam:='hoi';
    end.

  9. #9
    Rare, C achtige constructie. Ik zou het logischer vinden als er zou staan:
    Code:
    TPersonen = array of TPersoon;
    PPersonen = ^TPersonen;
    Netto ongeveer hetzelfde effect, maar uiteindelijk is het een stuk duidelijker dat het om een array gaat.
    Wel leuk dat het kan natuurlijk, vooral als je C code wilt vertalen
    1+1=b

  10. #10
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Ieuw, dat is net basic :-) Automated types en fundamentele types mixen, en alle marshalling voor lief nemen.

    Gecompliceerd omdat een dynarray al een reference type is, en refcounted. Het zou me niet verbazen als de bovenstaande code effectief een dubbele pointer is, en dus fout. Ik heb dit soort constructies wel vaker in .NETized code gezien, en vind ze erg gevaarlijk en verwarrend.

    Goleztrol: belangrijk is ook dat het consequenter is. B.v. Delphi staat het toe voor pchar, maar niet voor andere pointer types, terwijl pchar = ^char;

  11. #11
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Tiburon heeft hier inmiddels ook support voort

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Replies: 11
    Last Post: 23-Jan-05, 13:14
  2. Aanpassen van dynamische arrays
    By KillerB in forum Algemeen
    Replies: 5
    Last Post: 31-Aug-03, 20:59
  3. Dynamische arrays
    By RedPanda in forum Algemeen
    Replies: 15
    Last Post: 30-Jan-03, 20:51
  4. Replies: 0
    Last Post: 08-Jan-03, 00:42

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •