Q&A

  • 에러좀 봐주세요.
레코드 변수의 포인터 형의 배열을 사용하고 싶어서 다음처럼 하였는데요
실행할때  gvaryPDB[nLoop].name := G_MyCeContacts.Contact.PRENAME; 이부분에서
다음과 같은 에러가 납니다..


** 선언 **

TCDBRec = Record;

TpCDBRec=^TCDBRec;

gvaryPDB :  array of TpCDBRec;
///////////////////////////////////////////////////////
** 사용 **
for nLoop := 0 to 4 do
        begin
            Setlength(gvaryPDB, 4 );
            gvaryPDB[nLoop].name := G_MyCeContacts.Contact.PRENAME;
///////////////////////////////////////////////////////////////
** 실행에러 **

Access violation at address 004044DO in modlue. Write of address 0000010.

아무래도 인덱스값을 잘못줘서 그런거 같은데요 어떻게 고쳐야 될까여?
3  COMMENTS
  • Profile
    최용일 2002.08.30 06:14
    안녕하세요. 최용일입니다.

    포인터를 쓰실려면 먼저 메모리 할당을 받으셔야 합니다.

    GetMem이나 New등의 함수를 이용해서 메모리 할당 받고, 다 쓰신후에 FreeMem이나 Dispose등의 함수를 이용해서 메모리를 해제해주시면 됩니다.

    그리고 동적 배열의 메모리를 할당하는 SetLength는 for문 밖으로 빼야 겠네요...

    Setlength(gvaryPDB, 4 );
    for nLoop := 0 to 3 do // <= 여기도 3이 맞는거 같은데... 4자리 할당했으니까...
    begin
        New( gvaryPDB[nLoop] ); // 포인터에 메모리 할당
        gvaryPDB[nLoop].name := G_MyCeContacts.Contact.PRENAME;
        ......
    end;

    다 쓴후에...

    for nLoop := 0 to 3 do // <= 여기도 3이 맞는거 같은데... 4자리 할다했으니까...
    begin
        Dispose( gvaryPDB[nLoop] ); // 포인터의 메모리 해제
    end;
    Setlength(gvaryPDB, 0); // 동적배열해제

    ^^ 항상 즐코하세요...

  • Profile
    고지범 2002.08.31 02:44
    걍 지나가던 얼큰입다... 답변 중에.. 잠시 ... ^^

    Access violation 은 원본 코드 중...

    for nLoop := 0 to 4 do
            begin
                Setlength(gvaryPDB, 4 );
                gvaryPDB[nLoop].name := G_MyCeContacts.Contact.PRENAME;

    nLoop = 4인 경우에 발생하는 듯합니다.. 따라서 nLoop 가 3까지만 설정된다면 위의 코드는 원하는 데로 동작합니다. 왜냐면 SetLength의 경우 위에서 보면 동일한 크기의 메모리를 요구하고 있고, 현재 크기와 같기 때문에(nLoop = 0 일때 SetLength를 이용하여 설정된 크기...) for-loop 를 돈다고 해도 새로이 할당되지 않고 초기에 할당된 곳을 사용하기 때문이죠.

    그리고 Dynamic-Array (동적배열)의 경우, 초기에 SetLength를 사용하여 메모리를 잡아도 해제하는 코드는 불필요합니다. 왜냐하면 델파이에서 알아서 해제를 시켜주니까요... (델파이 5/6 기준입니다. 제가 델파이를 5부터 알았기 때문에...) 또한 동적배열을 Parameter로 함수 호출시에 계속 전달하여도 해제 코드가 불필요합니다. 이것 역시 델파이에서 알아서 해제시켜 주죠..
    따라서 New를 이용하여 새로이 받은 메모리만 Dispose를 이용하여 해제시켜주는 곳만 신경쓰신다면 에러의 부분을 해결하실 수 있을 겁니다...
  • Profile
    스말(^___^) 2002.08.30 06:26
    ^_________________^