포인터 관련 질문입니다.

게시판 IDL Q&A 포인터 관련 질문입니다.

태그: 

3 답변 글타래를 보이고 있습니다
  • 글쓴이
    • #676 Reply
      tlseorb0111
      회원

      안녕하세요 IDL 포인터 관련 질문입니다.

      여러 함수나 프로시저들간에 데이터를 주고 받을경우
      예를들어 아래와 같은 예제에서
      pro ex, a
      help, /mem
      end

      PRO test
      c = dindgen(1e7, 8)
      help, /mem
      ex, c
      END

      test 프로시저에서 선언된 c라는 배열을 ex 프로시저로 넘겨줄때
      test에는 c, ex에는 a라는 배열이 생성되서 c배열의 memory * 2 만큼의
      메모리를 차지하는 것인 줄 알고있었습니다.
      하지만 위의 예제를 돌려보면 프로시저가 돌아가는 동안 메모리는 c배열 하나만큼의
      크기만 차지하는 것 같은데요.

      포인터를 쓰는 이유 중 하나가 여러 프로시저나 함수들간에 대용량 데이터를 주고 받을 경우
      배열을 직접 주고 받는다면 동일한 데이터가 중복으로 생성되 비효율적이므로
      포인터를 넘겨줘 heap 메모리상에 저장된 변수을들 공유하는 방식으로 작업을 하는것이 좋다고
      알고 있습니다. (결과 적으로 메모리공간을 덜 잡아먹거나 메모리 공간을
      생성하는 시간을 줄이는 효과인것으로 이해가 됩니다.)
      하지만 예제처럼 배열로 넘겨주는 경우도 데이터가 중복 생성되지 않는경우라면
      포인터를 쓰지 않더라도 메모리 효율이 나빠지지 않을것 같은데요.
      이런 상황에서 포인터를 써서 얻는 이점이 무엇인지 궁금합니다.

      • 이 게시글은 tlseorb0111에 의해 10 years, 10 months 전에 수정됐습니다.
      • 이 게시글은 tlseorb0111에 의해 10 years, 10 months 전에 수정됐습니다.
    • #677 Reply
      tlseorb0111
      회원

      예제를 돌렸을때 출력되는 값입니다.
      heap memory used: 645674609, max: 645674609, gets: 271719313, frees: 271716341
      heap memory used: 645674609, max: 645674609, gets: 271719313, frees: 271716341

    • #684 Reply
      Jonghyuk
      회원

      기본적으로 동적 타이핑 언어들은 변수의 값이 Heap 영역에 저장된다고 보는 것이 맞습니다. 그렇지 않다면,
      a=fltarr(100)
      a=’abc’

      와 같은 것이 어렵겠지요(C에서 위와 같은 장난은 용납하지 않습니다만 IDL이나, PYTHON 같은 언어들은 이게 허용 됩니다. PYTHON은 사실상 모든 변수가 Object죠).

      어쨌든 간에, 제기하신 내용은 사실입니다. 이 사이트에 포스팅 된 글 Call by Value, Call by reference를 보시면, IDL에서 변수명을 넘겨주면 이것은 Call by Reference 로 작동합니다. C로 얘기하자면 포인터를 넘겨 주는 것과 같아요.

      그러면 포인터는 없어도 되는 거네요. 대부분 그렇습니다. 포인터 없이 IDL 을 사용하는 데 불편함이 거의 없습니다. 대부분의 IDL 사용자가 포인터를 모르고 사는 것도 그 이유입니다. 그리고 어차피 IDL의 포인터는 C의 포인터와 달라, 고속 Indexing 같은 개념으로 사용되지 않습니다(포인터 연산 없습니다). 정말 그럼 없어도 되는 건가요?

      1. 구조체의 필드는 한번 설정되면 Type을 바꿀 수 없습니다. 이 때 포인터를 사용합니다. GUI 영상 처리 프로그램을 만들 때, 사용자가 어떤 크기의 영상을 읽을지 모르지요. 이 때 영상 자료는 포인터를 이용하여 Heap 에 저장합니다. (IDL GUI에서 각각의 컴포넌트는 단 하나의 사용자 변수(uvalue)를 가집니다. GUI에서 어떤 이벤트가 발생하더라도, 이벤트 처리 프로그램으로 TOP GUI의 ID가 넘어갑니다. WIDGET_CONTROL을 이용하면 지정 위젯 ID에서 UVALUE를 가져올 수 있구요. 그래서 거의 표준 GUI 프로그래밍은 TOP GUI Component에 모든 GUI 정보를 때려 넣습니다). 그러니 영상 자료도 TOP GUI의 UVALUE 변수에 들어가야 하니 구조체의 필드로 들어가야 하고, 구조체의 필드는 한번 정해지면 타입, 배열의 크기 등을 바꿀 수 없으니, 자유를 얻기 위해 포인터를 사용합니다. 포인터가 가리키는 곳은 어떤 데이터든 들어올 수 있으니까요.

      2. WIDGET_CONTROL에 의해서 UVALUE를 넣거나 뽑아오는 과정은 일반적으로 복제가 일어납니다. 왜냐하면, 서브루틴과 서브루틴 간의 직접적 변수 교환이 아닌, “이벤트 처리 서브루틴”을 통한 자료 교환이거든요. 물론 이 때도 /NO_COPY 키워드를 이용해서 복제가 아닌, 그냥 REFERENCE 처럼 넘기는 방법도 있습니다(WIDGET_CONTROL의 /NO_COPY 키워드가 분명히 있어요. 이것의 위험성이 있어서 포인터를 씁니다. 잠시 후 설명하지요). 그러므로 GUI의 모든 정보를 담고 있는 변수(보통 state 변수를 씁니다. 당연히 일반적으로 구조체입니다)를 직접 던지고 받아도 됩니다. 만일 이 때 /NO_COPY를 안쓰면 이벤트 발생시마다 데이터 복제가 일어나서 속도 저하 있습니다.
      그럼 왜 /NO_COPY가 위험한가? GUI는 사용자의 예기치 못한 입력도 있으므로 Error Handling 이 적절히 이루어져야 합니다. 잘만든 프로그램은 이벤트 처리 루틴에서 잘못된 경우 뻗어버리지 않고, 아무일도 없다는 듯이 넘어가지요(호출했던 프로그램으로 그냥 돌아갑니다). 이런 상황에서 /NO_COPY 를 했다고 생각해 보십시오. 이벤트 처리 루틴에서 다시 SET_UVALUE를 못한 채 죽어버리는 경우라면 state 변수는 흔적도 없이 사라지는 셈입니다. (이래서는 안전한 에러처리의 방법이 없습니다).
      포인터를 쓰는 경우라면, 문제 없지요. Heap 에 자료는 그대로 보존되어 있으니까요.

    • #689 Reply
      tlseorb0111
      회원

      답변 감사합니다

3 답변 글타래를 보이고 있습니다
'포인터 관련 질문입니다.'에 답변달기
글쓴이 정보: