메인 컨텐츠로 가기

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관 보기.

developerWorks에 처음 로그인하면 developerWorks프로파일이 생성됩니다.귀하의 프로파일에서 동의하신 내용이 공개되지만 이 사항은 언제든지 변경 가능합니다. 귀하의 성명(숨김으로 체크되어 있어도 표시됩니다)과 디스플레이 이름은 게시한 컨텐츠나 사이트 엑세스시 표시됩니다.

모든 정보가 안전하게 전송되었습니다.

  • 닫기 [x]

처음 developerWorks에 로그인할 때 프로파일이 작성되므로, 이를 위해 디스플레이 이름을 선택해야 합니다. 선택하신 디스플레이 이름은 developerWorks에 게시한 컨텐츠에 표시됩니다.

3글자 이상 31글자 이하의 길이로 사용 가능합니다. dW커뮤니티 내에서는 보안상 이메일주소를 제외한 다른 이름을 지정하셔야 합니다.

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관 보기.

모든 정보가 안전하게 전송되었습니다.

  • 닫기 [x]

메모리 프로그래밍을 개선하자

보안성과 안정성을 개선하는 중급 기교를 소개한다

Cameron Laird, Vice President, Phaseit, Inc.
Photo of Cameron Laird
Cameron은 developerWorks에 오랫 동안 기고해 온 필자이자 전 컬럼니스트다. 주로 회사에서 개발을 촉진하도록 안정성과 보안을 높여주는 오픈 소스 프로젝트에 관심을 가지고 기사를 쓴다. AIX가 여전히 실험 단계에 있었던 20여년 전에 AIX를 처음 접했다. 이후로 다양한 메모리 디버깅 도구를 사용하고 개발했다.

요약:  메모리 폴트를 수정하느라 엄청난 시간을 보내는 데 지치지 않았나요? 메모리가 새거나, 메모리 경계를 위반하거나, 자료를 초기화하지 않았거나, 실행 시 메모리를 과도하게 잡아먹는 프로그램 때문에 늘상 골머리를 앓나요? 이 기사에서 까다로운 메모리 결함을 정복하는 기법을 소개합니다.

원문 게재일:  2008 년 4 월 29 일
난이도:  중급 영어로:  보기
페이지뷰:  1327 회
의견:  


앞서 "메모리 디버깅 기법"(참고자료 참조)이라는 기사를 통해 C/C++/자바 프로그램에서 메모리 결함을 줄이자고 역설했다. 또한 메모리 관리가 중요한 이유, 프로그램에서 흔히 저지르는 실수, 메모리 결함을 방지하고 수정하는 전략도 소개했다.

이 기사에서는 앞서 기사에서 미처 다루지 못했던 내용을 좀더 상세히 설명한다. 메모리 오류는 이미 수십 년 전에 정체가 밝혀졌음에도 불구하고, 오늘날까지 C/자바 프로그램에서 상당한 골치거리로 남아 있다. 나로서는 참으로 안타까운 심정이 드는 이유는 새 클라이언트와 일할 때마다 스레드 경쟁 조건, 난해한 트랜잭션 의미 문제, 성능 문제 등의 복잡미묘한 문제를 공략하기 전에, 가장 먼저 기본적인 메모리 할당 오류와 메모리 관련 결함을 제거하느라 시간을 보내는 경우가 허다하기 때문이다.

지금쯤이면 메모리 결함은 초보적인 오류가 되어야 마땅하지만, 아직도 업계에서는 정체불명으로 남아 있다. 하지만 좋은 소식이 있다. 모든 메모리 문제는 해결이 가능하다. 걱정은 붙들어 매시라. 프로그램 품질을 몇 배로 높이는 방법은 아주 간단하니까. 거창한 물리적 법칙을 어길 필요까지 없다. 그저 평소 버릇만 살짝 고치면 충분하다.

메모리 관리를 개선하기 좋은 환경

이 기사에서는 메모리 관리에 유용한 프로그래밍 도구를 소개한다. 기사를 읽는 동안 흔히 팀은 아래 세 가지 아이디어가 균형 잡힌 환경에서 구현 품질이 가장 높아진다는 사실을 명심하기 바란다.

  • 코드를 보는 눈
  • 자동화
  • 전문 지식

"코드를 보는 눈"이란 코드를 살펴보는 눈이 많을수록 좋다는 뜻이다. 짝 프로그래밍(pair programming), 검사(inspection) 등 어떤 기법이든 상관이 없다. 프로그램에 속하는 모든 부산물, 즉 모든 소스 코드와 모든 빌드 스크립트 등을 누군가 직접 살펴본다는 사실이 중요하다. 컴파일과 링크가 성공적이고 별다른 문제가 없어 보인다고 그냥 넘어가는 경우가 흔하다. 그래서는 안 된다. 기대 수준을 높여야 한다. 적어도 모든 소스 코드는 다른 사람이 읽고 이해할 필요가 있다.

자동화는 “실행 가능하게 만들기”라는 목표를 추구한다. 프로그램이 4초 안에 초기화를 끝내고 떠야 한다면, 이에 해당하는 테스트 케이스를 작성하라. 프로젝트 빌드에 문제가 있다면, 매일 밤 깨끗한 상태에서 출발하여 프로그램 전체를 다시 빌드하라. 일반적으로 컴퓨터 분야에서 무언가를 개선하려면, 올바른 동작 방식을 파악한 후, 답을 도구나 라이브러리나 기법으로 만든 다음, 지속적인 결론을 내놓도록 자동화하면 된다. 뻔한 작업이나 장황한 작업을 반복하느라 지루하고 짜증스럽다면 오히려 축하할 일이다. 자동화할 멋진 기회를 포착했으니.

자동화를 논할 때는 '자동화를 도와주는 도구에 대한 관심'과 '자동화를 지지하는 태도' 사이에서 균형을 잡기가 가장 어렵다. 무엇보다 성공에 가장 크게 기여하는 요소는 바로 품질을 향상시키겠다는 의욕과 꾸준한 노력이다. 어떤 도구도 이보다 더 효과적이지 못하다.

제품 기대 수준

코드 품질 제품

이 기사는 태도와 공정(process)이 중요하다고 강조한다. 어떤 도구를 사용하는가는 둘째 문제다. 도구가 중요하지 않아서가 아니라, 태도와 공정이 너무나 중요하기 때문이다.

코드 품질, 특히 메모리 결함을 다루는 분야에서 일하는 장점 중 하나가 시장이 성킁성큼 발전하는 모습을 지켜보는 즐거움이다. 편집기나 환경 설정 관리나 예측 등과 같은 도구는 지난 수년 동안 미미하게 발전했을 뿐이며, 사용하는 도구도 주관적인 “상황”에 따라 달라진다. 십여 년 전이나 지금이나 같은 방법으로 코드를 편집하고 관리하는 팀도 많다.

반면, 내가 지금까지 겪은 바에 따르면 코드 분석 도구 업체는 판매 후 지원과 개선 측면에서 단연코 독보적이라 하겠다. 우수한 자동화 도구가 문제를 찾아내는 수준도 놀랍지만, 고객과 협력해 난이한 퍼즐을 해결하려는 업체의 열성에도 항상 놀란다. 앞으로 도구는 빠르게 향상되리라 보인다. 또한 도구를 사용할수록 오류를 찾아내는 기교와 지식도 늘어나리라.

앞서 언급한 세 요소 중 가장 미묘한 요소가 전문 지식이다. 예를 들어, 도구를 설정하여 시스템으로부터 일일 보고서를 뽑아내기는 어렵지 않다. 그런데 my_source.c에서 285행 근처에 메모리 누수가 발견되었다고 치자. 우수한 조직이라면 문제를 고쳐야 한다는 사실에 동의한다. 그렇다면 구체적으로 어떤 조치를 취해야 할까?

답은 그리 간단하지 않다. 예를 들어, 삼바 개발팀은 자기네 원시 코드 품질에 굉장한 자부심을 자랑했다. 실제로도 삼바 코드는 품질이 뛰어났다. 하지만 Coverity, Inc.가 자사 소스 분석 제품으로 2006년에 삼바 개발팀에 오류 보고서를 제출하자, 삼바 프로그래머들은 첫 주 만에 198개를 되돌려 보냈다. 하지만 흥미롭게도 (처음에 팀이 “거짓 오류”라고 분류했던) 나머지 보고서 18개는 결국 (거의) 다시 구현했다. 이렇듯 구현 품질과 관련된 문제는 최고 프로그래머들조차도 금방 분석하고 판단하기 어려울 정도로 미묘하다.

메모리 관리 오류를 해결할 목적으로 코드를 다시 구현한다면 진짜로 전문적인 지식이 필요하다. 가장 노련하고 실력 있는 프로그래머를 투입하고 전문가로부터 도움을 받는 편이 좋다. 내 경험을 언급하자면, 프로그램 분석 도구를 구입한 경우는 도구 업체 지원팀으로부터 적극적인 지원을 받을 수 있었다. 오픈 소스 도구를 사용하는 경우는 메일링 리스트나 관련 채널을 통해 까다로운 문제를 해결할 수 있었다.

보는 눈이 충분하고, 자동화를 수행하고, 전문 지식이 있으면, 합리적인 수준에서 모든 소스 코드 품질 문제를 해결할 수 있다. 얼마나 놀라운 변화가 일어났는지 느껴보자. (C++와 자바가 그대로 이어 받은) C 개발 문화는 lint가 형편없던 20여 년 전 상태로 굳여져서 여전히 소스 코드 품질을 높여주는 최신 기술로 불리고 있지 않은가? 예전에는 소스 코드가 한 페이지만 넘어가도 이해하기 어렵고 통제 불능이라 여겼다. 이제 우리는 더 잘 할 수 있다. 오류가 없고, 경고가 없고, 누수가 없고, 철저히 검토하고, 스타일이 좋은 소스 코드를 충분히 짜낼 수 있다. 이러한 목표를 성큼 당겨주는 도구 몇 가지를 소개한다.


프로그램 분석 목표

우선 자신에게 익숙한 컴파일러를 사용한다. 기사 내용은 주로 C 프로그램에 초점을 맞추지만 C++/자바 프로그램에도 같은 원리가 적용된다. 자신이 사용하는 컴파일러에서 -O -Wall -W -Wshadow -pedantic에 해당하는 옵션을 사용한다. 이 컴파일러 지시자는 소스 코드에서 문법이 올바르지 않거나 의심스러운 부분을 보고하도록 만든다. 목표는 로그가 깨끗한 소스 코드다. 즉 프로젝트를 처음부터 깨끗하게 빌드하면 컴파일러 진단 메시지가 하나도 나타나지 않아야 한다.

어색하게 들릴지도 모르겠다. 많은 개발팀이 컴파일러가 제공하는 진단 결함을 불치병이나 세금처럼 필요악으로 취급한다. 그렇지 않다. 소스 코드가 수십만 아니 수백만 행에 이르더라도 모든 컴파일러 진단 오류를 체계적으로 없앨 수 있다.

그러면 두 가지 장점이 생긴다.

  • 진짜 기능 오류 몇 개만 남는다. 내 경험으로는 아무리 잘 관리해도 진단 메시지를 무시하는 50만 줄짜리 프로젝트는 오류가 적어도 5000개 정도 존재한다. 물론, 그 중 적어도 몇 개 정도는 자주 발생하는 오류로 드러난다. 결코 음수가 되지 않는 unsigned 정수를 조건으로 사용하거나, 선언한 변수에 철자 오류가 있어 전혀 사용되지 않는 경우 등이다. 모든 컴파일러 진단 메시지를 하나씩 없애가는 과정에서 코드 품질은 극적으로 향상된다. 컴파일러 진단 메시지는 자동화하기가 쉬우므로 비용도 적게 든다.
  • 진단 메시지를 모두 혹은 거의 없애고 나면 새로 생기는 오류를 찾아 격리하기가 훨씬 쉬워진다.

목표로 삼을 경고 수준은 -Wall에서 -Wall -W -Wshadow -Wredundant-decls ... -pedantic 사이다. 많은 팀이 기본으로 사용하는 -W 계열을 제거한 옵션은 적당하지 못하다. 타입 캐스트 경고 메시지를 처리하는 적절한 방법은 전문가마다 의견이 다를 수 있다. 하지만 포인터와 정수를 혼동하는 코드나 초기화되지 않은 변수를 경고하는 메시지를 끄는 편이 바람직하다고 주장할 사람은 없으리라.

내 주장을 뒷받침할 몇 가지 예제를 제시한다. 구현 품질을 높이는 방법, 특히 메모리 관리가 뛰어난 코드를 구현하는 첫 단계는 '경고 메시지가 없는 컴파일'이라는 사실을 명심한다


코드 예제

컴파일 옵션이 얼마나 중요한지 살펴보자. 예를 들어, 다음 코드에는 진단되지 않은 심각한 메모리 오류가 있다.


Listing 1. 진단되지 않은 심각한 메모리 오류
                    
      /* "cc -c example1.c"와
		      "cc -c -O -Wall example1.c"로 컴파일한다. */
      #include <stdio.h>
      
      int main()
      {
          int j;
      
          printf("%d.\n", j);
          return 0;
      }
    

확실히 변수 j를 초기화하지 않았지만 gcc를 비롯한 여러 컴파일러는 프로그램을 불평없이 컴파일한다. cc -c -O -Wall example1.c 혹은 좀더 강력한 옵션으로 컴파일하는 경우에만 ... warning: 'j' is ... uninitialized ...이라는 오류 메시지가 뜬다.

코드 검사와 단위 테스트를 주기적으로 수행하는 숙련되고 절제된 개발팀도 때때로 이런 실수를 저지른다. 그러므로 의도하지 않은 실수를 찾아내는 자동 검사가 필수적인 보완책이다. 적어도 하루에 한 번은 진단 메시지를 확인해야 한다. 아직까지 이러한 기본을 무시하는 회사가 있다면 변화할 필요가 있다. 지난 십여 년 동안 다양한 규모와 다양한 상황에 처한 개발 팀과 일했지만, 진단 자동화를 위한 lint-Wall 메시지에서 이익을 얻지 않은 팀은 하나도 없었다.

요즘 lint는 옛날 lint와 많이 다르다. 십여 년 전까지만 해도 컴파일러 경고 메시지는 (오류가 아닌 경우를 오류로 인식하거나 오류인 경우를 오류가 아니라고 인식하는 등) 잘못된 정보가 상당히 많았다. 하지만 지금은 상황이 크게 달라졌다. 특히 FlexeLint, Coverity, Grammatech, Parasoft, Klockwork 등과 같은 상용 제품은 매우 우수하다.

도구가 급격히 향상되면서 도구 지식이 많을수록 어려운 문제를 찾기도 쉬워진다. 다음 코드는 정적 분석과 런타임 분석이 모두 필요한 예제다.


Listing 2. 어려운 진단 예제
                    

      
      struct a {
          int b;
          int c;
      };
      void f2(), f3(int);
      
      
      int f1(int thing)
      {
          struct a x;
      
          if (thing < 0)
      	       x.b = 3;
          f2();
          if (thing < -3)
      	      f3(x.b);
          return 0;
      }
    

대다수 분석 도구는 x.b가 초기화되지 않았다고 보고한다. 숙련된 프로그래머라면 thing < -3일 때만 x.b를 계산한다는 사실을 이해한다. thing이 -3보다 작으면 당연히 thing < 0이니 x.b를 사용해도 문제가 없다. 그러나 대다수 분석 도구는 이를 추론하지 못한다.

이에 대응하는 방법은 여러 가지다. 분석 도구를 포기할 필요는 없다. 아니, 바람직하지도 못하다.

  • 대다수 분석 도구는 명령행에서 분석을 비활성화하는 지시자를 지원한다. 예를 들어, f3(x.b) 직전에 /*NOUNINITIALIZED*/라는 행을 추가할 수도 있다. 그러면 도구가 제공하는 장점은 그대로 취하면서, 유지보수 프로그래머에게 x.b 할당을 주의하라고 경고할 수 있다. 도구를 속이는 코드는 대개 사람 눈으로도 이해하기 어려운 "위험 지역"을 의미한다. 당장은 x.b가 초기화되었으므로 코드가 올바르다고 판단하더라도, 유지보수 과정에서 코드를 변경해 잘못된 상태로 만들 수도 있다. 그러므로 각 진단 메시지에 신중하게 대처해야 한다. 당장 진짜 오류가 아니라고 무심코 무시하기로 결정해서는 안 된다. 모든 진단 메시지는 중요하다.
  • 런타임 해석 도구라면 진단을 올바로 내렸을 가능성이 크다. 개인적으로는 모든 원시 코드에 정적 도구를 돌려야 한다고 믿지만, 런타임 도구만으로도 효과적인 전략을 설계할 수도 있다
  • 가장 단순하게 struct a x; 대신에 struct a x = {0};이라고 x를 초기화하는 방법도 있다. 내가 좋아하는 방법은 아니지만, 어떤 조직은 이 방법을 가장 선호한다. 실제로 이런 초기화 방식을 팀 구현 스타일로 정립한 팀도 있다.
  • 일반적으로 내가 선호하는 방법은 리팩토링이다. 명쾌한 설명을 위해, 잘못된 판단을 보여줄만큼 충분하도록 예제를 줄여보았다. 실제 예제는 훨씬 복잡하겠지만, Listing 3과 같이 코드 일부를 다시 작성하는 편이 훨씬 의미가 있다. 표현을 고쳐쓰는 방법은 분석 도구에서 경고를 없앨 뿐만 아니라 Listing 2를 수정한 경우와 같이 적어도 사람이 코드를 이해하기 쉽게 만들어준다.

Listing 3. Listing 2 다시 짜기
                    

      
      struct a {
          int b;
          int c;
      };
      void f2(), f3(int);

      void initialize_a(int thing, struct a *xptr)
      {
          if (thing < 0)
      	       xptr->b = 3;
      }
      
      int f1(int thing)
      {
          struct a x;
      
	  initialize_a(thing, &x);
          f2();
          if (thing < -3)
      	      f3(x.b);
          return 0;
      }
    

어떤 방법을 취하든 진단 경고에 대응하는 목표는 하나다. 단순히 경고를 끄지 말고, 응집성이든 가독성이든 유지보수성이든 적어도 어느 하나라도 개선하는 방향으로 나가야 한다.


도구를 선택하는 기준

코드 분석 도구는 선택하기 쉽지 않다. 이 주제 하나만으로도 기사 몇 개는 충분히 나온다. 하지만 그렇다고 주저해서는 안 된다. 간단한 기준 몇 가지를 소개할 테니 출발점으로 삼기 바란다. 일단 도구 하나를 선택해 몇 주 혹은 몇 달 정도 써보면 새 도구가 필요할지 기존 도구를 보완할지 대충 감이 잡힌다. 다행스럽게도 거의 모든 도구 업체가 평가판을 제공하므로, 오픈 소스 제품을 선택하든 라이선스 버전을 선택하든, 당장 프로그램에 적용할 수 있다.

이 기사가 다루는 관점에서 분석 도구는 크게 두 가지로 나뉜다. 하나는 정적 분석 도구이고, 다른 하나는 런타임 분석 도구다. 정적 분석 도구는 lint와 같은 방식으로 돌아간다. 원시 코드 전체를 읽어 분석한 후 오류와 경고를 보고한다. 정적 분석 도구는 단순히 분석 능력만이 아니라 통합성과 사용성도 중요하다. 간단한 lint는 보고하는 오류 유형이 제한적이다. 좀더 우수한 도구는 GUI와 명령행 뷰를 모두 제공하여 문제 감지에서 해결까지 격차를 줄여준다. 또한 일부 우수한 도구는 로컬 환경을 “학습”하도록 구성할 수도 있다. 즉 팀 환경을 구축해 특정 스타일을 장려하거나 금지할 수 있다.

가장 우수한 정적 분석 도구는 응용 프로그램 원시 코드를 모두 분석한다. 그래야 로컬이 아닌 조건을 분석할 기회가 생긴다. 예를 들어, 자바 원시 파일 30여 곳에서 특정 생성자에 똑같은 자료 유형을 넘기는 반면, 유일하게 한 곳에서 문법적으로는 맞지만 다른 유형을 넘긴다고 가정하자. 이처럼 특이한 경우는 코드 전체를 분석해야 찾아낼 수 있다. 이러한 유형의 경험적 테스트는 현재 활발히 연구 중인 분야다.

런타임 도구는 사용 방법과 기능 면에서 정적 분석 도구와 확연히 다르다. 런타임 도구는 프로그램을 특수한 환경에서 실행하여, 좀더 일반적으로는 프로그램에 보조 코드를 추가하여, 정상적인 방식으로 프로그램을 실행한 후 결과를 보고한다. 도구는 저차원 명령을 실행하면서 각 명령이 다음 규칙을 위배하는지 확인한다.

  • 배열 참조가 원래 정의된 배열 범위를 벗어나는가?
  • 이 할당으로 힙 메모리에 허상 참조가 생기는가?
  • 특정 위치에 있는 자료 값이 해당 위치를 참조하는 자료 유형인가?
  • 기타 등등

때로는 정적 도구와 동적 분석 도구를 놓고 상대적으로 우수성을 비교하는 사람들이 있다. 정적 도구는 동적 도구가 찾아내는 오류 전부에다 더 많은 오류를 찾아낸다거나 혹은 그 반대라거나 주장이 분분하다.

현실적으로 이러한 논쟁은 설득력이 없어 보인다. 나는 여러 정적 도구와 여러 동적 도구를 모두 즐겨 사용한다. 내가 보기에 차이점은 사용성 측면에 있다. 동적 도구를 사용하면 원시 코드가 없는 타사 라이브러리를 관리하기 좋다. 또한 최종 사용자가 프로그램을 실행하는 경우 사용자에게서 골치 아픈 정보를 숨기면서 자세한 보고서를 내놓는다. 게다가 런타임 도구는 특정한 실행 경로에서만 발생하는 (일반적으로 대단히 해결하기 어려운) 메모리 문제를 쉽게 찾아준다. 반면, 런타임 도구는 프로그램 실행 속력을 떨어뜨린다. 때로는 용납하지 못할 정도까지 떨어지기도 한다. 또한 도구가 내놓는 보고서를 이해하기가 쉽지 않다. 어떤 경우에는 라이선스 조건이 걸림돌이 되기도 한다. 라이선스 조건 때문에 특정한 제품을 못 쓰는 경우도 생긴다.

앞서 언뜻 언급했듯이, C 언어 말고 다른 언어도 분석 도구가 존재한다. 흔히 자바와 고차원 언어는 C보다 안전하다고 인식하지만 (즉 감지되지 않은 오류 발생률이 낮지만) 그래도 포트란, 자바, 파이썬, 루비 등을 포함하여 많은 언어에서 우수한 도구가 존재한다. C 같은 문제가 없는 함수(functional) 언어에서도 기존 디버깅 방식으로는 찾지 못하는 메모리 누수와 메모리 결함이 발생할 수 있다.


결론

프로그램은 버그가 있기 마련이다. 특히 C 프로그램은 메모리 결함이 생기기 쉽다. 그러나 메모리 결함이 아무리 까다롭고 흔하다 해도 해결이 가능하다. 코드 검사와 코드 분석이라는 잘 알려진 기술을 체계적으로 도입하면 많은 원시 코드 오류를 확실히 제거할 수 있다. 현 시점에서 코드 품질을 극적으로 높이는 관건은 기술적 혁신이 아니라 문화적인 혁신이다. 현재 나와 있는 도구와 기법은 대다수 메모리 결함을 해결하고 남는다. 메모리 결함을 찾아내는 핵심 열쇠는 메모리 오류가 없는 고품질 코드를 유지하는 일이 진정으로 가능하다고 믿는 태도에 있다.


참고자료

교육

  • "메모리 디버깅 기법 (한글)"은 메모리 관리가 중요한 이유, 흔히 저지르는 메모리 오류, 오류를 줄이는 구현 기법을 소개한다.

  • 삼바 프로젝트는 우수한 코드 품질로 명성이 높지만, Coverity라는 도구 개발업체가 만든 보고서를 보면 삼바에서 200여개나 되는 결함을 찾아냈다.

  • Andrew Glover가 developerWorks에 기고했던 기사 "In pursuit of code quality"는 자바에 초점을 맞추지만, 후속편 기사 "Refactoring with code metrics"는 C/C++ 개발에서 재사용 기술과 도구 자동화가 중요하다고 주장한다. Poonnam Chitable은 "Using IBM Rational PurifyPlus"에서 부제 "Performing runtime analysis with test automation"에 걸맞게 Purify에 국한하지 않고 다양한 분석 도구를 소개한다.

  • Bruce Tate가 2006년 developerWorks에 기고했던 기사 "Explore functional programming with Haskell"은 그 부제가 "부수 효과를 일으키지 않는 프로그래밍"이다. 전통적인 프로그래밍 언어와 비교해서 함수형(functional) 프로그래밍 언어는 메모리 누수, 배열 경계 침범, 메모리 손상 등 부정적인 부수 효과를 일으키지 못한다는 (혹은 고의적으로 시도해야만 겨우 가능하다는) 장점이 있다. 나는 고차원 언어가 개발자 생산성과 코드 안정성을 향상시킨다고 믿는다. 그러나 Haskell과 같이 아주 고차원 언어라도 메모리를 고려해야 하며, 따라서 고차원 언어에서도 우수한 보조 도구가 유용성을 발휘한다.

  • Expect는 명령행 프로그램을 자동화해주는 멋진 도구다. Expect를 사용하면 복잡한 스크립트를 짤 필요가 없다. 내가 Expect에 대한 글을 자주 쓰는 이유가 바로 여기에 있다. 개발 과정에서 프로그램을 분석 도구와 통합할 때는 자동화 기능이 필수다. 흔히 Expect가 이러한 역할을 수행한다.

  • 이 기사에 필요한 참고자료를 여기서 많이 찾아냈다.

  • "Avoid the Most Common Software Development Goofs"는 정적 C 코드 분석의 기본 개념을 소개한다.

  • AIX and UNIX: AIX 시스템 관리 기술을 익히고 유닉스 지식을 확장할 수 있다.

  • AIX and UNIX 입문 (한글): AIX와 UNIX 초보자에게 유용한 정보를 제공한다.

  • AIX 5L™ Wiki: AIX와 관련한 기술 정보를 모으는 위키 사이트다.

  • 이 기사의 필자가 쓴 다른 기사와 튜토리얼을 살펴본다.
  • 주제별로 AIX와 UNIX 라이브러리를 검색하자
  • Safari 온라인 서점: 다양한 다양한 기술 관련 서적을 제공한다.

  • developerWorks 기술 행사와 웹캐스트: developerWorks 기술 이벤트와 웹 캐스트를 놓치지 말기 바란다.

  • 포드캐스트: IBM 기술 전문가 이야기를 들어보자.

제품 및 기술 얻기

토론

필자소개

Photo of Cameron Laird

Cameron은 developerWorks에 오랫 동안 기고해 온 필자이자 전 컬럼니스트다. 주로 회사에서 개발을 촉진하도록 안정성과 보안을 높여주는 오픈 소스 프로젝트에 관심을 가지고 기사를 쓴다. AIX가 여전히 실험 단계에 있었던 20여년 전에 AIX를 처음 접했다. 이후로 다양한 메모리 디버깅 도구를 사용하고 개발했다.

잘못된 도움말 신고

부정사용 신고

감사합니다. 이 항목은 운영자가 관심을 표시했습니다.


잘못된 도움말 신고

부정사용 신고

제출실패 신고. 나중에 다시 실행해주세요.


디벨로퍼웍스 로그인


IBM ID가 필요하세요?
IBM ID를 잊으셨습니까?


비밀번호를 잊으셨습니까?
비밀번호 변경

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관.

 


developerWorks에 처음 로그인하면 developerWorks프로파일이 생성됩니다.귀하의 프로파일에서 동의하신 내용이 공개되지만 이 사항은 언제든지 변경 가능합니다. 귀하의 성명(숨김으로 체크되어 있어도 표시됩니다)과 디스플레이 이름은 게시한 컨텐츠나 사이트 엑세스시 표시됩니다.

화면상에 보여지는 닉네임을 정하세요.

처음 developerWorks에 로그인할 때 프로파일이 작성되므로, 이를 위해 디스플레이 이름을 선택해야 합니다. 선택하신 디스플레이 이름은 developerWorks에 게시한 컨텐츠에 표시됩니다.

3글자 이상 31글자 이하의 길이로 사용 가능합니다. dW커뮤니티 내에서는 보안상 이메일주소를 제외한 다른 이름을 지정하셔야 합니다.

3개의 &이나 대쉬를 포함해주시고 31글자내로 제한해주세요.


developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관.

 


아티클 순위

의견

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=20
Zone=AIX와 UNIX
ArticleID=304552
ArticleTitle=메모리 프로그래밍을 개선하자
publish-date=04292008
author1-email=claird@phaseit.net
author1-email-cc=mmccrary@us.ibm.com

태그

Help
검색 필드를 사용하여 My developerWorks 내에서 해당 태그가 사용된 모든 종류의 컨텐츠를 검색하십시오.

태그를 더 많이 보거나 적게 보기 위해 슬라이더 막대를 사용하십시오.

인기 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 최고 인기 태그를 보여줍니다.

내 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 귀하의 태그를 보여줍니다.

검색 필드를 사용하여 My developerWorks 내에서 해당 태그가 사용된 모든 종류의 컨텐츠를 검색하십시오. 인기 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 최고 인기 태그를 보여줍니다. 내 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 귀하의 태그를 보여줍니다.