문제

TStringList에 문자열을 추가하는 데 문제가 있습니다.다른 게시물을 검색했지만 이에 대한 답변을 찾을 수 없습니다.

내가 하려는 것은 TStringList에 많은 양의 문자열(14000개 이상)을 추가하는 것이지만 프로세스 어딘가에서 EAccessViolation을 얻습니다.내가 사용하는 코드는 다음과 같습니다.

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;

¿이 코드에 어떤 문제가 있나요?목록에 중복된 문자열이 포함되어 있으므로 Duplicates 재산 dupAccept.다음을 사용하여 목록을 로드할 수 있었습니다. LoadFromFile, 하지만 내 응용 프로그램 외부에 텍스트 파일을 갖고 싶지 않습니다.

당신이 나를 도울 수 있기를 바랍니다 !!!추가 정보가 필요하면 알려주십시오.

매우 감사합니다.당신의 도움에 정말 감사드립니다.

도움이 되었습니까?

해결책

외부 파일을 사용하기위한 제안은 여기에 표시됩니다. 그러나 게시물은 외부 파일이 없다는 욕구를 나타냅니다. 그런 다음 파일을 실행 파일에 리소스로 연결하는 것이 좋습니다. 다음 단계에 따라이 작업을 쉽게 수행 할 수 있습니다.

모든 문자열을 StringData.txt (또는 선택한 이름)라는 텍스트 파일에 배치하십시오. 그런 다음 선택한 이름의 .rc 파일을 작성하고 다음을 넣습니다 (String_data는 선택한 식별자가 될 수 있음).

STRING_DATA RCDATA "stringdata.txt"

.rc에서 .res 파일을 만듭니다.

BRCC32 <name of rc>.rc

이제 소스 코드 에서이 파일을 참조하십시오. 장치에 다음 위치를 놓으십시오.

{$R <name of res>.res}

파일 스트림에서로드하는 대신 리소스 스트림에서로드 :

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

명령 줄 자동 빌드를 수행하는 경우 .rc 파일을 소스 컨트롤 아래로 유지하고 빌드 프로세스 중에 .res를 빌드하는 것이 좋습니다. 이러한 방식으로 stringData.txt 파일을 소스 컨트롤 아래로 유지할 수 있으며 .txt 파일이 변경 될 때마다 .RES 파일을 명시 적으로 빌드하지 않고도 다음 빌드에서 모든 편집이 자동으로 잡혔습니다.

다른 팁

어떤 델파이 버전을 사용하고 있습니까?일부 이전 버전에는 너무 큰 크기로 배열을 재할당하려고 할 때 액세스 위반을 일으킬 수 있는 메모리 관리자 버그가 있었습니다.

추가해 보세요 빠른MM4 프로젝트에 이전 메모리 관리자를 교체하고 도움이 되는지 확인하세요.

또한 목록을 외부 파일에 보관하는 것이 더 나을 것입니다.예, 이는 다른 파일이지만 전체 프로그램을 다시 컴파일하지 않고도 목록을 변경할 수 있다는 의미이기도 합니다.또한 업데이트 생성(및 배포)도 더 쉬워집니다.

메이슨은 아마도 AV의 원인에 맞을 것입니다. 이것은 성장하기에 상당히 큰 배열입니다.
참고로, StringList에서 긴 처리를 수행 할 때는 업데이트 이벤트를 발사하지 않기 위해 StringList/EndupDate가 주변을 둘러싼 것이 좋습니다.
지금은 없더라도 나중에 추가 될 수 있고 문제가 발생할 수 있습니다.

목록을 작성한 직후에 추가하려는 항목 수로 목록을 설정하십시오. 또는 목록을 RC 파일 (프로젝트 이름이 아닌 다른 이름)에 배치하고 프로젝트에 추가하십시오. 이는 응용 프로그램에 컴파일되지만 목록을 작성하기 위해 실행 가능한 코드가 포함되지 않습니다.

또한 14,000 라인 절차로 컴파일러 무결성에 대해 걱정합니다. 사람들은 합리적인 일을 넘어서서 다양한 방식으로 컴파일러를 깨뜨리는 다른 사례를 발견했습니다.

ADD 메소드가 훨씬 다른지 확실하지 않지만 ThashedStringlist를 시도하고 속도 부스트를 볼 수 있습니다 (이 기능은 아니지만).

코드 대신 다음을 사용하여 문자열을 StringList에 추가하십시오.

var
str : 문자열;
시작하다
str : = '125-샘플' + #13 #10;
str : = str + 'tcumson' + #13 #10;
str : = str + 'atlv 4300' + #13 #10;
str : = str + '150t-15' + #13 #10;
................

list.text : = str;

끝;

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top