IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Limite de la taille d'un TBits


Sujet :

Langage Delphi

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Limite de la taille d'un TBits
    Bonjour,

    A l'aide en ligne de Delphi, il est écrit :
    "TBits permet de stocker et d'accéder à un nombre illimité de valeurs booléennes"
    J'ai une application dans laquelle TBits.Size peut atteindre 6 Mo. Or, à l'affectation du champs TBits.Size à 6 Mo cela déclanche une erreur EAccessViolation.
    Si l'aide en ligne Delphi dit vrai, je suppose qu'il faut paramétrer la mémoire disponible par le menu option de Delphi.
    Quelqu'un peut-il me dire comment résoudre ce problème ?
    Mille merci

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 519
    Points : 25 037
    Points
    25 037
    Par défaut
    TBits.Size à 6 Mo
    Euh, 6 Mo = 6291456 o, mais on parle de Size en Bit donc ça ne fait que 786432 Octets alloués !
    Et comme c'est un pointeur, ce n'est pas sur la pile donc les options de compilation n'auront pas d'influence
    Pile : $00004000 à $00100000 (4Ko à 1Mo)

    Moi, cela fonctionne avec D6, bon j'ai triché avec une classe TBits modifié pour accéder au propriété privée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    procedure TFrmTestMemory.ButtonTBitsClick(Sender: TObject);
    var
      MyBits: TMyBits;
      I: Integer;
    begin
      MyBits := TMyBits.Create();
      try
        for I := 6291450 to 6291450 + 1000 do
        begin
          MyBits.Size := I;
          Memo.Lines.Add(Format('%d Bits = %d Octets', [MyBits.Size, MyBits.MemSize]));
        end;
        for I := 6291450 * 8 to 6291450 * 8 + 2048 do
        begin
          MyBits.Size := I;
          Memo.Lines.Add(Format('%d Bits = %d Octets', [MyBits.Size, MyBits.MemSize]));
        end;
      finally
        MyBits.Free();
      end;
    end;
    C'est un copier coller, avec quelques modifs pour ce topic

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    type
      TMyBits = class
      private
        FSize: Integer;
        FMemSize: Integer;
        FBits: Pointer;
        procedure Error;
        procedure SetSize(Value: Integer);
        procedure SetBit(Index: Integer; Value: Boolean);
        function GetBit(Index: Integer): Boolean;
      public
        destructor Destroy; override;
        property Bits[Index: Integer]: Boolean read GetBit write SetBit; default;
        property Size: Integer read FSize write SetSize;
        property MemSize: Integer read FMemSize;
      end;
     
    const
      BitsPerInt = SizeOf(Integer) * 8;
     
    destructor TMyBits.Destroy;
    begin
      SetSize(0);
      inherited Destroy;
    end;
     
    procedure TMyBits.Error;
    begin
      raise EBitsError.CreateRes(@SBitsIndexError);
    end;
     
    procedure TMyBits.SetSize(Value: Integer);
    var
      NewMem: Pointer;
      OldMemSize: Integer;
     
      function Min(X, Y: Integer): Integer;
      begin
        Result := X;
        if X > Y then Result := Y;
      end;
     
    begin
      if Value <> Size then
      begin
        if Value < 0 then Error;
        FMemSize := ((Value + BitsPerInt - 1) div BitsPerInt) * SizeOf(Integer);
        OldMemSize := ((Size + BitsPerInt - 1) div BitsPerInt) * SizeOf(Integer);
        if FMemSize <> OldMemSize then
        begin
          NewMem := nil;
          if FMemSize <> 0 then
          begin
            GetMem(NewMem, FMemSize);
            FillChar(NewMem^, FMemSize, 0);
          end;
          if OldMemSize <> 0 then
          begin
            if NewMem <> nil then
              Move(FBits^, NewMem^, Min(OldMemSize, FMemSize));
            FreeMem(FBits, OldMemSize);
          end;
          FBits := NewMem;
        end;
        FSize := Value;
      end;
    end;
     
    procedure TMyBits.SetBit(Index: Integer; Value: Boolean); assembler;
    asm
            CMP     Index,[EAX].FSize
            JAE     @@Size
     
    @@1:    MOV     EAX,[EAX].FBits
            OR      Value,Value
            JZ      @@2
            BTS     [EAX],Index
            RET
     
    @@2:    BTR     [EAX],Index
            RET
     
    @@Size: CMP     Index,0
            JL      TBits.Error
            PUSH    Self
            PUSH    Index
            PUSH    ECX {Value}
            INC     Index
            CALL    TBits.SetSize
            POP     ECX {Value}
            POP     Index
            POP     Self
            JMP     @@1
    end;
     
    function TMyBits.GetBit(Index: Integer): Boolean; assembler;
    asm
            CMP     Index,[EAX].FSize
            JAE     TBits.Error
            MOV     EAX,[EAX].FBits
            BT      [EAX],Index
            SBB     EAX,EAX
            AND     EAX,1
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Points : 757
    Points
    757
    Par défaut
    Ne voulais tu pas plutôt écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        for I := 6291450 to 6291450 + 1000 do
        begin
          MyBits.Size := I;
          MemoConcatVsFormat.Lines.Add(Format('%d Bits = %d Octets', [MyBits.Size, MyBits.MemSize]));
        end;
        for I := 786432 * 8 to 786432 * 8 + 1000 do
        begin
          MyBits.Size := I;
          MemoConcatVsFormat.Lines.Add(Format('%d Bits = %d Octets', [MyBits.Size, MyBits.MemSize]));
        end;

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 519
    Points : 25 037
    Points
    25 037
    Par défaut
    Non !
    J'ai prévu les abus de langage ! et l'ambiguité des unités !
    Affecter 6 Mo à Size n'a pas de sens, puisque c'est un nombre de Bits !
    Cas 1 : 6 Millions de Bits
    Cas 2 : 6 Million d'Octet alloué !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Points : 757
    Points
    757
    Par défaut
    OK !

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut 6 Mo de bits n'ont peut-être pas de sens mais sont réels
    Mille excuses j'ai dit 6Mo au lieu de dire 6MBits. Pour information;
    Mon appli porte sur l'impression tramée (offset, Helio, etc. )
    Les feuilles à imprimer font 103 cm x 72 cm
    On utilise pour chaque encre primaire C,M,Y,K une "forme imprimante" de même dimension pour tranférer l'encre sur le support. Cette forme est réalisée en numérique et contient une trame qui est réalisée par une image TIF 1 Bit.
    Chaque point de trame fait donc 1 Bit qui est ouvert ou fermé pour laisser passer l'encre.
    Pour un traitement spécifique, cette trame peut donc être inscrite dans un TBits. L'image en 2400 dpi occupe donc (2400*103/2.54)*(2400*72/2.54) bits.
    Faites le calcul cela atteind et dépasse 6 Mo/8.
    Je vais essayer la méthode de ShaiLeTroll à qui je précise qu'il s'agit de 6 millions de bits et non d'octets
    A+

  7. #7
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    (2400*103/2.54)*(2400*72/2.54)

    6Mega pixels ? vraiment ?

    97 344 * 68 032 = 6 622 507 008 pixels (6.6 Giga-pixels)

    à 1bpp = 827 813 376 bytes (800Mo)


    2400 dpi = pixel par inch
    on as déja 2400*2400 = 5 760 000 pour une image de 1x1 inch (5.6MP)
    donc pour une image de 40.55 x 28.35 inchs ...
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 519
    Points : 25 037
    Points
    25 037
    Par défaut
    Ah ben, si on nous donne les mauvais chiffres ...

    Voilà la problème est résolu, Size étant un Entier, et 6 milliard étant largement plus qu'un entier, c'est donc impossible, ou alors ça donne un nombre négatif, et Windows ne doit pas aimer que l'on demande un nombre négatif d'octets ... c'est illimité à 2 milliard, lol, vachement fini l'infini, dommage en théorie, on aurait pu allouer 17.1 milliard (16 en pratique à cause du MM et Win32 qui n'autorise que 2Go pour TOUT le processus et que l'on dépasse pas 1960Mo en réalité)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    803
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 803
    Points : 182
    Points
    182
    Par défaut Peut on déclarer une structure TGigaBits
    Peut-on déclarer une structure de type TBits mais où Size ne serait plus déclaré Integer mais Uint64 ?
    Je n'ai pas trouvé le source de l'unité Classes dans laquelle est déclaré Tbits. Où trouver ce source ?
    Si la taille de cette structure peut atteindre un entier 64 bits non signé quid de l'utilisation de Win32 ? ne faut-il pas obligatoirement passer par Win 64 ?

  10. #10
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 519
    Points : 25 037
    Points
    25 037
    Par défaut
    Je pense avoir fournir le code plus haut (un TMyBits qui offre FMemSize en publique alors que totalement inaccesible dans TBits) ... tu peux le modifier ... tu as aussi le code de Dr Who

    Pour avoir le code source, faut une version pro, ent ou architecte ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WCF] Limitation dans la taille des objets
    Par dev01 dans le forum Windows Communication Foundation
    Réponses: 3
    Dernier message: 30/08/2012, 08h18
  2. Réponses: 6
    Dernier message: 06/01/2009, 21h30
  3. [SQL-Server] mssql_fetch_array : limitation de la taille de chaine de caratère?
    Par narutobaka dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 12/11/2008, 09h49
  4. [Divers] Limitation de la taille des lignes
    Par apqmwnqmap dans le forum Cobol
    Réponses: 13
    Dernier message: 18/12/2007, 10h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo