Q&A

  • 동적배열의 포인터 사용에 대한 다른 질문입니다.. ㅠ.ㅠ
최용일님과 이중철님의 답변은 잘 봤습니다..
그런데 제가 테스트를 해 보았는데..
그것보다 더 이전의 문제점이 해결되지 않고 있습니다.. ㅠ.ㅠ

main()
var
   a : array of word;
begin
   fn1(@a);

   edit1.text:=inttostr(a[0]);
   edit2.text:=inttostr(a[1]);
end;

fn1(b : pointer);
type
   tarrayword = array of word;
begin
   b:=allocmem(sizeof(word)*2);

   tarrayword(b)[0]:='11';
   tarrayword(b)[1]:='22';
end;

이런 식으로 프로그램을 짜는게 제 목표인데요.
즉, 메인 함수에서 동적 배열이 선언되어 있는데,
서브함수에서 동적 배열을 포인터로 넘겨받아서
크기를 결정하고(메모리를 allocation하고), 값을 저장하여
메인함수에서 사용하고자 하는게 목적입니다.

그런데, 서브함수에서는 잘 저장되는데
메인함수에서 값을 사용하려고 하면
access violation 에러가 납니다.. ㅠ.ㅠ

프로그램 상에서 어떤 점이 잘못되었나요? ㅠ.ㅠ

2  COMMENTS
  • Profile
    이중철 2003.12.22 19:42
    이번에도 최용일님의 답변에 추가해서 올립니다.

    먼저 다이나믹 및 배열은 Setlength가 더 안정적이고요

    그리고 메모리 할당은 해당 스레드에서 생성하시고 소멸하는것이

    정상입니다.

    저도 이것땜시 골머리 썩히다가 C로 한번 해봤는데 C는 아에 처음

    부터 에러 나더군요..

    그리고 먼저 님께서 쓰신 문장이 어떤것이 틀렸는지 볼까요..

    일전에도 말씀 드렸듯이 Dynamic Array 변수는 포인터 라고

    말씀드렸죠.. 정상적인 운영법 부터 올리께요

    var a : array of word;
    begin   <= 변수만 선언하면 a 에는 NULL 이 있습니다. 즉, 0 입니다.
          
        SetLength(a, 10);  <= 바로 이때 a 라는 변수에
                                      힙에 10개의 word의 메모리 영역을 정하고
                                       그 첫번째 포인터를 a에 반환합니다.

        fn1(a);      <= a에는 이미 포인터주소값이 담겨졌으니..
                          
      
    end;

    fn1(b : pointer);
    type
       tarrayword = array of word;
    begin
       b:=allocmem(sizeof(word)*2);  <= 이와 같은 재할당이 있으면
                                                        위와 같은 방법은 안됩니다.

       tarrayword(b)[0]:='11';
       tarrayword(b)[1]:='22';
    end;



    그런데 님께서 fn1에서 리사이징해서 쓸려고 한다. 이럴때는
    function fn1 : pointer;
    type
       tarrayword = array of word;
    begin
       reslut :=allocmem(sizeof(word)*2);
       tarrayword(b)[0]:='11';
       tarrayword(b)[1]:='22';
    end;
    이렇게 하고
    메인에서
    var a : array of word;
    begin   <= 변수만 선언하면 a 에는 NULL 이 있습니다. 즉, 0 입니다.
        a := fn1;      <= 이런식으로 하면 a에는 할당된 주소가 담기겠죠
    end;

    최용일님께서 올리신 방법은 저도 많이 써요.. 위의것은 이렇게도 많이

    쓴다는 것일뿐 정석은 아니에요. 최용일님께서 쓰신 방법을 전 오히려

    더 많이 쓰죠 (어쩌다 실수로 3중 포인터까지 갈 경우도 있지만)

    최 용일님께서 올리신 방법의 장점은 제가 서술했던 방법보다 더 가용성

    이 많습니다.

    main

    type
       tarrayword = array of word;
    var a : ^tarrayword;
         (이 의미는 array of word 의 첫번째 포인터가 담겨있는 포인터를
          a에 정의 하겠다는 것입니다.
          이 경우 a에는 값이 정의 됩니다. a에는 상기 포인터의 포인터값이
          담겨져 있습니다. 바로 이 특징이 있어 더욱 가용성이 뛰어나죠
          이것이 왜 이럴까는 곰곰히 생각하시면 쉽게 이해 될꺼에요);
    begin  
        fn1(a);      
    end;

    fn1(b : pointer);
    type
       tarrayword = array of word;
    begin
       b^:=allocmem(sizeof(word)*2);  <= 이와 같은 재할당이 됩니다.
       tarrayword(b^)[0]:='11';
       tarrayword(b^)[1]:='22';
    end;

    위의 방법까지 Local, 즉 DLL을 사용하지 않을때는 잘 먹힙니다.

    그러나 DLL을 사용시 위의 방법중 2, 3번째는 주의가 요망됩니다.

    정확히 말하면 DLL에서 리사이즈 한것은 먹히기는 하지만

    알다시피 생성을 했으면 소멸을 해야 하는데 메인 프로그램에서

    소멸이 안됩니다. (메인에 소멸자 넣으면 되는것 같지만

    결국 메모리 Leak걸림 <= 어떻게 안될까 저도 고민 제가 구력이

    짧아서 메인에서 소멸은 못시키고 있음 DLL에서 생성하고 소멸을

    합니다. )

    결국 DLL에서 생성을 했으면 그 책임(생성을 한 책임)에 대한 의무

    (소멸을 할 의무)도 DLL에서 해야 합니다.


  • Profile
    최용일 2003.12.21 08:25
    안녕하세요. 최용일입니다.

    동적배열과 string형은 AllocMem, GetMem, New등의 함수대신에 SetLength란 함수를 써서 메모리를 할당받는것이 훨씬 안정적이구요...

    동적배열과 string 형은 자체적으로 메모리 할당/해제를 하므로 DLL내에서 사용한다면 동기화에 문제가 생길 수 있습니다.

    동적 배열보다는 배열의 포인터를 사용하시는것을 추천합니다.

    type
        PAW = ^TAW;
        TAW = array[0..(MAXINT div 2)-1] of Word;

    Main()

    var
        AW : PAW;
    begin
        Fn1(Pointer(AW));

        Edit1.Text := IntToStr(AW[0]);
        Edit2.Text := IntToStr(AW[1]);
        FreeMem(AW);
    end;

    procedure Fn1(var BW : Pointer);
    begin
        BW := AllocMem(SizeOf(Word) * 2);

       PAW(BW)[0] := 11;
       PAW(BW)[1] := 22;
    end;

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

    • 전형도
    • 2003.12.22 06:30
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2003.12.22 08:47
      안녕하세요. 최용일입니다. OnKeyUp이벤트에서 크기 체크해서 두번째 에디트박스로 포커스 이동시켜보세...
    • 전형도
      2003.12.22 20:15
      감사합니다...하나 더 궁금한것이 있어서요....... 그러면 주민등록번호를 입력할때 에디터박스 1개를 ...
    • romantic
      2003.12.22 20:16
      그건 'MaskEdit'를 쓰면 될텐데요. ㅡㅡ
    • 아폴론
    • 2003.12.22 04:05
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2003.12.22 08:43
      안녕하세요. 최용일입니다. FileCreate를 반드시 사용하고 싶으시다면 이미 존재하는 파일을 지우시고 ...
    • 이중철
      2003.12.22 19:55
      Editbox에는 OnExit라는 이벤트가 있거든요.. 이것은 Editbox에서 포커스가 들어 왔다가 잃을때 발...
    • 박희경
    • 2003.12.21 23:13
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 김도성
    • 2003.12.21 22:34
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2003.12.22 03:10
      안녕하세요. 최용일입니다. 굳이 API를 쓰시는 것 보다는 걍 모들로 호출해서 쓰시는게 좋을거 같은데.....
    • 최주영
    • 2003.12.21 21:29
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2003.12.22 03:05
      안녕하세요. 최용일입니다. 셋다 모두 가능합니다. 첫번째는 IE Extension쪽으로 자료를 찾아보시면 ...
    • 최주영
      2003.12.22 07:06
      안녕하세요 반갑습니다. 그리고 고맙습니다. 우선 한가지 부터 해결하기로 했습니다 . 역시나 한꺼...
    • 최용일
      2003.12.22 08:34
      안녕하세요. 최용일입니다. MSDN에서 찾아보세요... MSDN에 IE에 관한것만 따로 나온곳이 있는데... 정...
    • 최용일
      2003.12.21 08:48
      안녕하세요. 최용일입니다. TCanvas의 StretchDraw란 메소드를 이용해서 비트맵을 그려주시면 됩니다. ...
    • 이충무
      2003.12.22 22:32
    • 김병만
      2003.12.21 05:36
      감사합니다. 올려주신 파일로 해결했습니다.
    • 죠그셔틀
      2003.12.21 03:26
      제가 알기론 Delphi의 Design Time시에 환경을 관리해주는 유닛으로 알고 있습니다. 이 Unit을 이용...
    • 달파란
    • 2003.12.20 18:06
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 성더기
      2003.12.22 18:50
      IBOleDb라는 파일입니다 델세상(http://www.delphiworld.net) 자료실이나 팁란을 뒤적거려 보시면 파일이...
    • 김지영
    • 2003.12.20 09:05
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 백털성물
      2003.12.20 18:01
      스트링 그리드의 행자체는 TStrings라는 객체입니다.. 선택한 행자체를 넘긴다면 해당 한수의 변수를 같은...
    • 김지영
      2003.12.21 03:25
      우선 답변 감사드려요... ^^ 그런데.. 여러행을 한꺼번에 넘기려면 어떻게 해야할지 감이 안잡히네요.. ...
    • 최용일
      2003.12.21 08:58
      안녕하세요. 최용일입니다. 여러가지 방법이 있습니다. 님말씀처럼 구조체배열에 넣으셔두 되구... 리스...
    • 김지영
      2003.12.21 23:26
      감사 감사 감사드려요... ^^ 좋은 하루 되세요~~~
    • 김지수
    • 2003.12.20 08:36
    • 2 COMMENTS
    • /
    • 33 LIKES
    • 이중철
      2003.12.22 19:42
      이번에도 최용일님의 답변에 추가해서 올립니다. 먼저 다이나믹 및 배열은 Setlength가 더 안정적이고요...
    • 최용일
      2003.12.21 08:25
      안녕하세요. 최용일입니다. 동적배열과 string형은 AllocMem, GetMem, New등의 함수대신에 SetLength란 ...
    • Crazy
      2003.12.21 02:04
      소스가 없어서 확실한 원인은 알기 힘들지만 제 생각으로는 조회하는 쪽에 문제가 있는듯 보입니다. 중간...
    • 백털성물
      2003.12.20 18:09
      VCL의 영역중 프로퍼티 등록영역에 해당 VCL를 선언하세요.. 즉.. type   test = class(); p...
    • Crazy
      2003.12.21 02:13
      출력버튼 전에 처리하신다면 디테일의 레코드 카운트로 처리하면 될것 같은데요. Ex) if Query2.RecordCo...
    • 윤혜정
    • 2003.12.19 23:54
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2003.12.20 00:50
      안녕하세요. 최용일입니다. ExtractStrings란 함수를 써보세요... var     Str...
    • 최용일
      2003.12.19 23:27
      안녕하세요. 최용일입니다. 폼에다 직접 그리실려면 폼의 OnPaint이벤트에서 그려주는 루틴을 작성하셔...
    • 박수용
    • 2003.12.19 22:25
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2003.12.19 22:54
      안녕하세요. 최용일입니다. ActiveX언로드시키고 타입라이브러리 열어서 CLSID를 고치세요... 델파이...
    • 박수용
      2003.12.19 23:29
      확장자가 tlb인데요 tbl은 없습니다. 그리구요 refresh imp....란 툴바버튼은 어떤건가요. 처음부터 자...
    • 최용일
      2003.12.19 23:32
      안녕하세요. 최용일입니다. tlb가 맞습니다. 제가 실수했네요... 걍 알아들으시지... 타입라이브러리...
    • 박수용
      2003.12.20 00:43
      너무너무 감사드립니다. 감기 조심하세요.
    • 이중철
      2003.12.19 23:18
      다이나믹 어레이 자체가 포인터 입니다. 예로 var p : pointer; begin   p := p1; end; ...
    • 최용일
      2003.12.19 22:15
      안녕하세요. 최용일입니다. 형선언해서 형변환해서 쓰시는게 편해요... type    &nb...
    • 박준영
    • 2003.12.19 03:24
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 성더기
      2003.12.19 22:53
      해당 쿼리나 테이블 컴포넌트를 더블클릭하여 TField가 생성되어 있는지 확인해 보세요..
    • nilriri™
      2003.12.19 17:36
      아래 온라인 도움말의 내용입니다.. 예전 제 기억으론 pk에 지정할수 있는 컬럼 갯수에 제한이 있었던거...
    • 델초보
    • 2003.12.19 03:18
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2003.12.19 22:44
      안녕하세요. 최용일입니다. 레지스트리보다는 Shell API함수를 이용하세요... uses ......, ShlObj; ...
    • nilriri™
      2003.12.19 19:12
      샬롬~ ㅡㅡ; 98에선 테스트해보니까..바탕 화면 이라고만 나오네여..ㅡㅡ; 왜그러는지?? 그럼..즐...
    • nilriri™
      2003.12.19 19:26
      98 HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders xp HKEY_CUR...