Question

J'ai un problème d'ajouter des chaînes à une TStringList. J'ai cherché d'autres postes mais n'a pas pu trouver une réponse à cette question.

Ce que je suis en train de faire est d'ajouter une grande quantité de cordes à un TStringList (plus de 14000), mais quelque part dans le processus que je reçois un EAccessViolation. Voici le code que je utilise:

procedure TForm1.FormCreate(Sender: TObject);
begin
    List := TStringList.Create;
    List.Duplicates := dupAccept;
end;

procedure TForm1.ButtonStartClick(Sender: TObject);
begin
    List.Clear;
    List.Add('125-AMPLE');
    List.Add('TCUMSON');
    List.Add('ATLV 4300');
    List.Add('150T-15');
    List.Add('TDL-08ZE');
    List.Add('RT20L');
    List.Add('SIN LINEA');
    List.Add('TIARA');
    List.Add('FL200ZK1');
    List.Add('FL250ZK1');
    List.Add('SIN LINEA');
    List.Add('CENTAURO-70 S.P.');
    List.Add('CORSADO');

{ This list continues to about 14000 strings...}

    List.Add('VOSJOD 2');
    List.Add('Z 125');
    List.Add('ZUMY');
    List.Add('NEW AGE 125');
    List.Add('SIN LINEA');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    FreeAndNil(List);
end;

¿Quel est le problème avec ce code? La liste contient des chaînes en double donc je définir la propriété Duplicates à dupAccept. J'ai pu charger la liste à l'aide LoadFromFile, mais je ne veux pas avoir un fichier texte en dehors de mon application.

J'espère que vous pouvez me aider !!! S'il vous plaît me dire si vous avez besoin de plus d'informations.

Merci beaucoup. Je vous remercie de votre aide.

Était-ce utile?

La solution

Les suggestions pour l'utilisation d'un fichier externe sont sur la marque ici. Cependant, votre message indique que votre désir de ne pas avoir un fichier externe. Je vous suggère alors lier le fichier à l'exécutable comme une ressource. Vous pouvez facilement faire, procédez comme suit:

Placez toutes les chaînes dans un fichier texte appelé stringdata.txt (ou quel que soit le nom que vous choisissez). Ensuite, créez un fichier .rc quel que soit le nom que vous choisissez et il faut mettre dans ce (STRING_DATA peut être un identifiant que vous choisissez):

STRING_DATA RCDATA "stringdata.txt"

Créez un fichier .res du .rc:

BRCC32 <name of rc>.rc

référence maintenant ce fichier à partir du code source. Placez le suivant quelque part dans l'unité:

{$R <name of res>.res}

Au lieu de charger à partir d'un flux de fichiers, la charge d'un flux de ressources:

StringData := TResourceStream.Create(HInstance, 'STRING_DATA', RT_RCDATA);
try
  List.LoadFromStream(StringData);
finally
  StringData.Free;
end;

Si vous automatisé construit la ligne de commande, je vous suggère de conserver le fichier .rc sous contrôle de source et de construire .RES au cours du processus de construction. De cette façon, vous pouvez également conserver le fichier stringdata.txt sous contrôle de source et toutes les modifications sont pris automatiquement sur la version suivante sans avoir à construire explicitement les .res à chaque fois que les modifications du fichier .txt.

Autres conseils

Quelle est la version Delphi utilisez-vous? Certaines versions plus anciennes ont un bug dans le gestionnaire de mémoire qui peut provoquer une violation d'accès lors de la tentative de réallouer un tableau à une taille qui est trop grand.

Essayez d'ajouter FastMM4 à votre projet pour remplacer l'ancien gestionnaire de mémoire et voir si cela aide.

En outre, vous êtes probablement mieux garder la liste dans un fichier externe. Oui, il est un autre fichier, mais cela signifie aussi que vous pouvez modifier la liste sans avoir à recompiler l'ensemble du programme. Cela rend également la création (et la distribution!) Mises à jour plus facile.

Mason est probablement bon pour la cause de l'AV; c'est un assez large éventail de croître.
Sur une note de côté, lorsque vous faites un traitement long sur un StringList, il est recommandé de l'entourer par BeginUpdate / EndUpdate pour éviter de tirer tout événement de mise à jour.
Même si vous n'avez pas maintenant, ils pourraient être ajoutés plus tard et vous obtiendrez des problèmes.

Définir list.capacity au nombre d'articles que vous prévoyez d'ajouter, immédiatement après avoir créé la liste. Vous pouvez également placer la liste dans un fichier RC (nom autre que le nom de votre projet) et l'ajouter à votre projet. Cela sera compilé dans votre application, mais ne comporte pas de code exécutable pour créer la liste.

Je voudrais aussi vous soucier de l'intégrité du compilateur avec une procédure de ligne 14 000. Les gens ont trouvé d'autres cas où aller au-delà des pauses quoi que ce soit raisonnable le compilateur de diverses manières.

Vous pouvez également essayer THashedStringList, pourrait voir une augmentation de la vitesse (mais pas dans cette fonction), bien que je ne suis pas sûr si la méthode d'ajout est bien différent.

essayez d'utiliser les éléments suivants au lieu de votre code pour ajouter les chaînes à la StringList

var
Str: string;
commencer
  Str: = '125 AMPLE' + # 13 # 10;
  Str: = Str + 'TCUMSON' + # 13 # 10;
  Str: = Str + 'ATLV 4300' + # 13 # 10;
  Str: = Str + '150T-15' + # 13 # 10;
  ................

List.Text: = Str;

fin;

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top