블로그 이미지
대갈장군

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

2011. 3. 12. 04:33 프로그래밍/Windows API
드디어 실제로 메모리 주소 공간을 들여다 볼 차례...

http://technet.microsoft.com/en-us/sysinternals/dd535533 에서 VMMap 프로그램을 다운 받아서 실행시키면 현재 내 컴퓨터에서 돌아가고 있는 프로세스의 주소 공간을 들여다 볼 수가 있다.


김상형님의 책에 있는 샘플 프로그램을 돌리고 있는 샘플 프로세스의 메모리 주소 공간을 보여준다. 알다시피 프로세스는 총 4GB의 주소 공간을 가지지만 실질적으로 사용자가 사용하는 주소 공간은 0x00010000 부터 0x7FFEFFFF 이다. 대략 2GB 이다. 0x00000000 부터 0x0000FFFF 까지는 준비된 영역으로 접근시 Access Violation이 일어난다. 그리고 2GB 이후의 공간은 운영체제가 필요로 하는 주소 공간이다. 뭔 2GB 씩이나 쓰냐고 하겠지만 2GB도 작아서 3GB로 확장 하게 만들어 놨을 정도다.

아무튼, 위 그림에서 보면 아래쪽에 좌악 주소 공간의 크기 순으로 정렬되어 있는데 타입이 여러가지가 있다. 우선 Free는 할당 되지 않은 공간을 말하고 Private Data의 경우는 시스템의 페이징 파일에 맵핑 되어 있는 것을 말한다. 그리고 Image의 경우는 exe나 DLL 같은 이미지 파일을 맵핑 하고 있는 것을 말하고 Mapped File은 당연히 메모리 맵에 맵핑된 데이터를 말한다. 그리고 Heap도 보이는데 이것도 사실은 Private Data로 분류되고 있다.  

이렇게 펼쳐놓고 보니 메모리 별거 아니다... ㅡ.ㅡ 라고 믿고 싶다. 일단 메모리의 구조에 대한 이해가 끝났다면 다음으로 고고고~
posted by 대갈장군
2011. 3. 12. 04:15 프로그래밍/Windows API
마지막으로 힙과 메모리 맵이 남았다. 힙은 프로세스의 주소 공간 상의 예약 영역으로 가상 메모리 (VirtualAlloc 함수) 방식에 비해서 훠어얼씨인 더 효율적이다. 다만 '예약' 상태가 없기 때문에 편리성은 쬐에끔 떨어진다.

간단하게 결론만 말해서 작은 데이터의 연속적인 생성과 삭제 그리고 접근이 필요하다면 당연히 힙을 이용해야 한다. 만약 거대 메모리를 할당해야 한다면 VirtualAlloc 함수를 이용하여 적극적인 '예약'을 통해 보다 효율적으로 주어진 주소 공간을 사용하면 된다. 그리고 마지막으로 무지막지하게 큰 데이터를 불러와야 하거나 프로세스 간에 서로 메모리를 공유해야 한다면 최선의 방식은 메모리 맵이다.

힙의 할당과 해제는 다음과 같은 명령으로 수행 가능하다.
ptrHeap = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
HeapFree(GetProcessHealp, 0, ptrHeap);

사실 힙은 사용하는 방법은 간단한 편인데 왜 힙이 좋은 녀석인가에 대한 논의가 좀 필요하다. 우선 힙이 어떤 원리를 가지는가 알아보면, 힙은 프로세스 실행시 기본으로 1MB의 영역을 예약하게 된다. 중요한 것은 이 주소 공간은 프로세스가 가지는 다수의 스레드에서 접근 가능하므로 운영체제는 힙에 대해 순차적 접근 및 처리를 기본적으로 하게 된다. 다수의 스레드에 의한 경쟁 상태를 방지 하기 위해서 이다.

고로 바로 이 순차적 처리 부분에서 성능의 저하가 약간 있을 수 있다. 하지만 힙은 여러개 생성할 수 있으며 생성시에 HEAP_NO_SERIALIZE 플래그를 주면 동기화 문제를 고려하지 않고 즉각적인 접근과 변경을 허용하게 된다.

만일 다수의 스레드가 접근해서 읽기와 쓰기를 하는 경우라면 반드시 순차적 접근을 하도록 내버려 두어야 하지만 만약 사용자가 단일 스레드를 위한 하나의 힙을 생성하고 그 스레드만 접근한다는 보장이 된다면 순차적 접근을 무시하도록 하여 보다 빠른 성능을 내게 할 수 있다.

또한 하나의 통일된 힙에 모든 자료와 데이터가 섞이게 되는 경우 자료 A의 오류로 인한 자료 B로의 침범이 일어났을때 에러가 발생하면 운영체제는 자료 B에 의한 에러로 오판 할 수 있다. 

적절한 새로운 힙의 생성은 메모리 공간을 보다 효율적으로 사용하게 해주는 방법이 되기도 한다. 다양한 크기의 자료가 뒤섞여있는 힙에서는 조각화 현상이 나타나게 되므로 실제로 비어있는 여유 공간이 추가적인 데이터를 삽입하기에 충분하더라고 데이터의 배열 문제로 공간이 없다고 생각하게 된다. 이런 문제는 같은 사이즈를 가지는 데이터 별로 힙을 생성해 관리하면 쉽게 해결된다. 

그런 식으로 함으로써 추가적으로 유사한 데이터들이 한 주소 영역에 뭉치는 결과를 가져오며 이것은 시스템 램과 페이징 파일 사이의 스와핑을 줄여준다. 사실 이 스와핑이야 말로 성능 저하의 가장 큰 주범인데 이것을 예방 할 수 있다면 아주 효과적이라고 할 수 있겠다.

그리고 앞서 말했듯이 단일 스레드가 단일 힙을 엑세스 한다는 조건만 만족시켜주면 순차적 접근을 할 필요가 없으므로 동기화 비용을 줄일 수 있다. 

마지막으로 빠른 해제도 가능하다. 해제해야 할 데이터가 한군데 모여 있기 때문에 해제가 매우 빠르다. 마구 마구 섞여 있는 경우에는 해제도 번거롭다.

이런 여러가지 이유 때문에 힙은 아주 유용하게 쓰일 수 있는 놈이다. 

이런 장점을 이용해 클래스의 오브젝트 생성시 힙을 따로 할당하는 방법을 제프리 리처의 WIndows via C/C++ 책에서는 제시하고 있다. 작은 데이터 구조를 여러개 관리하는 프로그램에서는 매우 효과적인 클래스 관리법이 될 수 있을 것 같다.

메모리 맵은 하드디스크 공간에 존재하는 파일을 메모리로 맵핑 시키는 기법이다. 이로써 서로 다른 프로세스가 하나의 맵 파일을 공유할 수 있고 프로세스 간에 자료 교환이 가능하다. 


posted by 대갈장군
2011. 3. 11. 23:54 프로그래밍/Windows API
윈도우에서 메모리를 할당하는 다음 방법은 VirtualAlloc() 함수다. 이 함수는 malloc 함수에서 보다 발전된 형태로 사용자에게 여러 가지 추가 기능을 제공한다.

가장 큰 차이점은 '예약'과 '확정' 상태가 존재한다는 것인데 malloc의 경우 '확정' 상태만 있었다. 여기에 예약이 추가 되었는데 이로써 보다 효율적인 메모리 사용이 가능해 졌다. 예약만 한 경우 물리적 메모리는 전혀 소모되지 않는다. 오직 확정에만 가상 메모리가 실제로 할당된다.

함수의 원형은 다음과 같다.
LPVOID WINAPI VirtualAlloc( __in_opt  LPVOID lpAddress, __in      SIZE_T dwSize, __in      DWORD flAllocationType, __in      DWORD flProtect );

첫번째 인자가 할당하고자 하는 주소의 위치 (4GB의 프로세스 주소 공간에서), 두번째 인자는 할당할 크기, 세번째 인자는 할당 타입인데 바로 여기서 확정, 예약, 높은 번지 할당등을 설정할 수 있다. 자세한 내용은 다음 표 참조. 마지막 인자는 할당할 페이지의 엑세스 타입 설정을 하는데 이것도 malloc과의 다른점 중에 하나다. 읽기 쓰기 접근 제한 설정이 가능하다.

ValueMeaning
MEM_COMMIT
0x1000

Allocates physical storage in memory or in the paging file on disk for the specified reserved memory pages. The function initializes the memory to zero.

To reserve and commit pages in one step, call VirtualAlloc with MEM_COMMIT | MEM_RESERVE.

The function fails if you attempt to commit a page that has not been reserved. The resulting error code is ERROR_INVALID_ADDRESS.

An attempt to commit a page that is already committed does not cause the function to fail. This means that you can commit pages without first determining the current commitment state of each page.

MEM_RESERVE
0x2000

Reserves a range of the process's virtual address space without allocating any actual physical storage in memory or in the paging file on disk.

You can commit reserved pages in subsequent calls to the VirtualAlloc function. To reserve and commit pages in one step, call VirtualAlloc with MEM_COMMIT | MEM_RESERVE.

Other memory allocation functions, such as malloc and LocalAlloc, cannot use a reserved range of memory until it is released.

MEM_RESET
0x80000

Indicates that data in the memory range specified by lpAddress and dwSize is no longer of interest. The pages should not be read from or written to the paging file. However, the memory block will be used again later, so it should not be decommitted. This value cannot be used with any other value.

Using this value does not guarantee that the range operated on with MEM_RESET will contain zeroes. If you want the range to contain zeroes, decommit the memory and then recommit it.

When you specify MEM_RESET, the VirtualAlloc function ignores the value offlProtect. However, you must still set flProtect to a valid protection value, such as PAGE_NOACCESS.

VirtualAlloc returns an error if you use MEM_RESET and the range of memory is mapped to a file. A shared view is only acceptable if it is mapped to a paging file.

간단한 예를 보면, 


ptr = (int *)VirtualAlloc(NULL, sizeof(int)*10, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
VirtualFree(ptr, sizeof(int)*10,MEM_DECOMMIT);
VirtualFree(ptr, 0, MEM_RELEASE);
VirtualFree에 대한 설명이 빠졌는데 메모리 해제 함수다. MEM_DECOMMIT은 확정 해제, MEM_RELEASE는 예약 해제다. 메모리 할당도 MEM_RESERVE와 MEM_COMMIT를 같이 불러 호출하거나 따로 각각 두번 호출해야 한다. malloc보다 좀 번거롭긴 하다.

예약을 할 수 있다는 차이점 이외에도 할당 단위의 차이가 있다. 일단 일반적인 컴퓨터를 기준으로 봤을때 4K 사이즈로 할당이 이루어 진다. 즉, 내가 10K 할당을 요구하면 4의 배수인 12K로 할당한다는 말. 그리고 할당을 시작하는 할당 단위가 있다. 보통의 경우 64K 단위로써 매우 큰 편이다. 즉, 작은 사이즈의 메모리를 여러번 반복적으로 할당하게 되면 할당을 시작하는 단위를 64K로 끊기 때문에 메모리의 조각화가 심해진다. 

그래서 작은 메모리의 할당에는 malloc이 훨씬 더 경제적이다. 그런 경우에는 다음에 알아볼 힙을 사용하는 것도 좋은 방법이다. 

VirtualAlloc의 다른 재미있는 점은 접근 권한 설정이 가능하다는 점인데 너무 보안에 신경을 쓴게 아닌가 싶다.. ㅡ.ㅡ 또 다른 한가지 흥미로운 점은 메모리 잠금 기능인데 할당된 메모리를 물리적 RAM에 상주 하도록 잠그는 함수다. 이로써 보다 빠른 접근 속도를 제공하는데 잘못 사용하면 사용가능한 물리적 RAM을 제한함으로써 운영체제 전체에 속도저하를 유발할 수 있다. 

내가 봤을때 마이크로 소프트에서 야심차게 내놓은 메모리 할당 / 해제 함수인 것 같은데 소규모 프로그램 개발자에게는 그닥 매력적이지 않다. 물론 가능한 기능들은 malloc에 비해서 많고 예약과 확정이라는 효율적인 메커니즘을 제공하기는 하지만 작은 용량을 가지는 다수의 메모리를 반복적으로 할당해야 하는 경우 VirtualAlloc은 메모리 낭비가 너무 심히다.



'프로그래밍 > Windows API' 카테고리의 다른 글

윈도우 메모리 파이널!  (0) 2011.03.12
윈도우 메모리 - 4 (힙과 메모리 맵)  (0) 2011.03.12
윈도우 메모리 - 2 (malloc 함수)  (2) 2011.03.11
윈도우 메모리 - 1  (0) 2011.03.10
윈도우 - 차일드, 팝업  (0) 2009.11.17
posted by 대갈장군
2011. 3. 11. 03:20 프로그래밍/Windows API
앞서 언급했던 윈도우 메모리에 관한 이야기 2탄으로 바로 malloc() 함수에 대한 이야기다.

malloc은 뭐 워낙 유명한 함수라서 굳이 이야기 안해도 사용하는 방법쯤은 다 알거라 생각한다. 바로 코드로 들어가 보자.

   
   1:  #include <stdio.h>
   2:  #include <stdlib.h>
   3:  #include <string.h>
   4:   
   5:  #ifdef _DEBUG
   6:  #include <vld.h>
   7:  #include <vldapi.h>
   8:  #endif
   9:   
  10:  void main()
  11:  {
  12:      // Test int
  13:      int *ptr;
  14:      ptr = (int*)malloc(sizeof(int)*10);
  15:   
  16:      for(int i = 0; i < 10; i++)
  17:      {
  18:          ptr[i] = i * 10;
  19:          printf("ptr[%d] = %d\n", i, ptr[i]);
  20:      }
  21:   
  22:      free(ptr);
  23:   
  24:      // Test char
  25:      char *ptr_char;
  26:      ptr_char = (char *)malloc(sizeof(char)*20);
  27:   
  28:      char *str1 = "MEMORY LEAK";
  29:      strcpy(ptr_char, str1);
  30:   
  31:      printf("ptr_char = %s\n", ptr_char);
  32:   
  33:      free(ptr_char);
  34:   
  35:      // Test array of pointers
  36:      int **double_ptr;
  37:   
  38:      double_ptr = (int **)malloc(sizeof(int *)*10);
  39:   
  40:      for(int i = 0; i < 10; i++)
  41:      {
  42:          double_ptr[i] = (int *)malloc(sizeof(int)*10);
  43:          for(int j = 0; j < 10; j++)
  44:          {
  45:              double_ptr[i][j] = (i * 10) + j;
  46:              printf("double_ptr[%d][%d] = %d\n", i, j, double_ptr[i][j]);
  47:          }
  48:      }
  49:   
  50:      for(int i = 0; i < 10; i++)
  51:      {
  52:          free(double_ptr[i]);
  53:      }
  54:   
  55:      free(double_ptr);
  56:   
  57:  }

위의 코드의 제일 윗부분에 라인 6번과 7번을 보면 vld.h 라는 녀석이 있는데 이 녀석은 이른바 visual leak detector라고 불리는 오픈 소스로서 메모리 누수가 발생하면 콘솔 출력창에 어디서 뭐가 왜 어떻게 유출되었는지 상세 정보를 보여주는 아주 착한 놈이다.

이 오픈 소스는 http://www.codeproject.com/KB/applications/visualleakdetector.aspx 에 가면 다운 받을 수 있다.

코드는 세 파트로 나뉘어져 있는데 첫번째 파트에서는 간단하게 10개의 int 메모리를 할당하고 0 에서 9까지 넣어 출력했고 두번째 파트는 char 메모리 공간을 생성하여 MEMORY LEAK라는 섬뜩한 문구를 출력해 봤고 마지막은 이중 포인터를 이용해서 2차원 int 배열을 생성하여 0부터 99까지 각 배열에 대입 후 출력해 봤다.

암튼, 22번 라인, 33번 라인 그리고 50번에서 55번까지 free()로 할당된 메모리를 해제하는 명령들이 나와있는데 메모리는 할당보다 해제가 더 중요하다. 화장은 하는 것보다 지우는 것이 더 중요한 것 처럼... 

예를 들어 두번째 테스트는 Test char 파트에서 free()를 호출 안하면 (라인 33번 지우면), 다음과 같은 에러가 프로그램 종료 후 출력창에 뜬다.


너무나도 친절하게 얼마만큼의 메모리가 누수되었는지 그리고 들어있던 내용은 무엇인지 그리고 게다가 코드의 어느 부분에서 누수가 있었는지 알려준다... 너무 친절해서 눈물이 날 지경이다..

라인 33번에서 55번까지는 이중 포인터의 개념인데 integer 값을 10개 저장하는 배열을 10개 만들었다. 즉, 10 x 10 = 100 개의 int 배열을 만든 셈이다. 중요한 것은 해제인데 해제 할때는 10개의 개별 배열을 모두 하나씩 해제한 후 마지막에 이중 포인터를 해제 한다. 만약 개별 배열들을 해제하지 않고 이중 포인터만 해제해 버리면 10개의 개별 배열은 부모 잃어버린 자식들이 되므로 메모리 누수가 일어난다. 

개별 배열(자식)을 해제 하기 전에 이중 포인터 (부모)를 날려 버리면 자식들을 찾을 수가 없다. 왜냐면 부모 연락처가 없기 때문에... 

malloc을 이용한 할당은 가장 경제적인 메모리 할당이다. 왜냐면 바이트 단위로 사용자가 원하는 만큼 할당하기 때문이다. 좀 있다 살펴볼 다른 메모리 할당 함수는 malloc 처럼 바이트 단위로 할당을 하지 않는다. 경제적인 것은 그만큼 손이 많이 간다. 고로 해제하는 과정을 사용자가 반드시 꼼꼼히 해야 한다는 불편함이 있다. 


posted by 대갈장군
2011. 3. 10. 05:56 프로그래밍/Windows API
보다 나은 개발을 위해서는 윈도우 메모리에 대해서 전반적인 이해가 필요로 된다. 내가 김상형님의 책을 좋아하는 이유는 김상형님은 책을 쓰실때 항상 '왜' 라는 질문에 대답을 해주시기 때문이다.

과거 16비트 시절의 메모리 구조는 한 마디로 요약하자면 '위험천만'이었다. 가장 큰 문제는 사용자가 잘못 작성한 프로그램이 건드려서는 안되는 중요한 메모리 영역을 건드릴 수 있었다는 점이다. 메모리가 '전역 변수' 처럼 모든 프로그램 및 운영체제에게 통일된 표기 방식으로 공개 되어 있었기 때문이다.

그래서 실수로 운영체제의 영역을 지우거나 바꿔버리면 심지어 윈도우를 다시 깔아야 하는 말도 안되는 불상사가 종종 있었다고 한다. 안타깝게도 나는 그런 일을 겪어볼 행운(?)이 없었다. 

그러면서 32비트 운영체제가 도입되고 윈도우 95/98로 넘어오면서 드디어 새로운 메모리 체계가 완성된다. 바로 '가상 메모리' 시스템이다. 

가상 메모리는 간단히 말해서 물리적 메모리 + 페이징 파일이다. 여기서 물리적 메모리는 우리가 너무나 너무나 잘 알고 있는 바로 RAM이고 페이징 파일은 RAM을 흉내내고 있는 하드 디스크의 일부를 말한다.

RAM은 속도가 빠르지만 용량이 충분하지 않고 페이징 파일은 하드디스크를 이용하므로 용량은 방대하나 RAM에 비해 속도가 떨어진다.

하지만 이것이 전부가 아니다. 가상 메모리를 이용하는 운영체제는 각 프로그램이 운영체제가 제공하는 최대 주소 공간을 각 프로그램에게 할당해 준다. 즉, 32비트 운영체제라면 4GB의 주소 공간을 각 프로그램 다시 말하자면 하나의 프로세스에 할당해 준다.

이 4GB의 주소 공간은 사실 껍데기에 불과하며 물리적 메모리가 아니다. 예를 들어 malloc 함수를 통해 메모리 할당을 요청하면 프로그램이 가지고 있는 4GB 주소 공간의 어딘가에 요청한 메모리가 할당되었다고 알려주지만 실제로는 가상 메모리에 실질적인 메모리가 할당된 후 할당된 주소가 '페이지 테이블'이라고 불리는 맵에 저장되고 4GB에 할당 된 것 처럼 보이는 메모리는 실제로는 가상 메모리로 자동 연결되게 되어 있다.

이런 식의 이중 연결을 구현하는 이유는 이렇게 함으로써 이 프로그램이 다른 프로그램의 주소 영역, 혹은 운영체제의 고유 메모리 영역을 아예 터치 할 수 없도록 차단해 주기 때문이다. 고로 프로세스 A가 망해도 A만 망하지 B,C,D 기타 운영 체제에게는 눈꼽만큼의 영향도 안준다.

이는 16비트 운영체제의 단점을 한방에 커버 시켜주는 그야 말로 최대 강점이다. 최대 강점이면서 동시에 최대 단점이다. 왜냐면 프로세스간에 통신이 겁나 복잡해 졌기 때문이다. 보안성의 강화는 접근성을 약화 시킬수 밖에 없다.

다음 글타래에서는 가상 메모리 시스템에서 메모리를 할당하는 다양한 방법에 대해서 알아보자. 


posted by 대갈장군
2011. 3. 9. 01:36 나의 이야기

 

What is the most resilient parasite?

- 가장 생명력이 강한 기생충이 무엇인가?

 

A bacteria? A virus?

- 박테리아? 바이러스?

 

An intestinal worm?

- 장에 기생하는 벌레?

 

Uh...

- 음...

 

What Mr. Cobb is trying to say-

- Mr. Cobb 씨가 하려는 말은,

 

An idea.

- '생각' 입니다.

 

Resilient. Highly contagious.

- 질기고 매우 전염성이 강하죠.

 

Once an idea has taken hold of the brain, it's almost impossible to eradicate.

- 한번 머리속에 자리를 잡은 하나의 생각은 제거하는 것이 거의 불가능에 가깝습니다.

 

An idea that is fully formed, fully understood, that sticks.

- 완전히 형성되고 완전히 이해되버린 달라 붙은 생각. 

 

Right in there somewhere.

- 바로 거기 어딘가.

 

인셉션은 개인적으로 매우 뛰어난 영화라고 생각한다. 영화 제목부터 시작해서 배우의 연기, 내용, 흐름, 결말까지 그 모든 것이 통일된 하나의 의미를 가리키고 있다. 

그중에서도 가장 의미심장한 대사가 바로 위에 번역한 대사가 아닐까 싶다. 위 대사를 듣는 순간 망치로 머리를 한대 맞은 것 같았다.

가장 질기고 생명력이 강한 기생충은 바로 '생각'이라는 것. 많은 것을 암시하는 한 문장이다.

한번 사람의 머리 속에 어떠한 것에 대한 생각이 자리잡히게 되면 그 생각을 깨기 위해서는 그 이상의 것이 필요하다. 내가 현재 진실이라고 믿고 있는 것이 거짓이 아니길 바라는 사람의 감정적인 심리 요소도 그런 틀을 깨기 어렵게 만드는 이유중에 하나라고 생각한다.

내가 지금 믿고 진실들이 과연 진실일까? 라는 생각을 되뇌이게 만든 이 영화, 무서운 영화다. 내가 믿고 보고 말하는 진실들이 결국은 내 머리 속에서 굳어진 생각에서부터 나온 일부라는 것.

소름끼치도록 무서운 진실을 이야기 하고 있는 영화. 그래서 이 영화가 더 마음에 든다...




'나의 이야기' 카테고리의 다른 글

조용필 - 꿈  (0) 2013.05.20
범죄와의 전쟁  (0) 2013.01.24
진실 = 변하지 않는 마음  (0) 2010.02.23
Alaska  (0) 2010.02.18
기도  (2) 2010.02.03
posted by 대갈장군
2010. 9. 25. 01:58 프로그래밍/Visual C++ 2008
/MT, /MD, /MTd, /MDd 와 같은 컴파일 옵션에 따라 링크 되는 라이브러리가 다르다.
일단 정적으로 링크하게 되면 libcmt.lib 또는 libcmtd.lib가 선택이 되며 동적으로 링크할 경우 msvcrt.lib와 msvcrtd.lib가 선택된다. 이들의 차이는 정적 / 동적 링크이며 d가 붙으면 디버그 모드, 없으면 릴리즈 모드다.

C run-time library

Associated DLL

Characteristics

Option

Preprocessor directives

libcmt.lib

None, static link.

Multithreaded, static link

/MT

_MT

msvcrt.lib

msvcr80.dll

Multithreaded, dynamic link (import library for MSVCR80.DLL). Be aware that if you use the Standard C++ Library, your program will need MSVCP80.DLL to run.

/MD

_MT, _DLL

libcmtd.lib

None, static link

Multithreaded, static link (debug)

/MTd

_DEBUG, _MT

msvcrtd.lib

msvcr80d.dll

Multithreaded, dynamic link (import library for MSVCR80D.DLL) (debug).

/MDd

_DEBUG, _MT, _DLL

msvcmrt.lib

msvcm80.dll

C Runtime import library. Used for mixed managed/native code.

/clr

 

msvcurt.lib

msvcm80.dll

C Runtime import library compiled as 100% pure MSIL code. All code complies with the ECMA URT spec for MSIL.

/clr:pure

 

헌데 재미 있는 것은 Visual C++는 추가적으로 헤더의 선언 유무에 따라 Standard C++ library도 링크한다는 것이다. 자, 여기서 조금 헷갈리는데 위의 테이블은 분명 Visual C++의 프로젝트 옵션의 컴파일 설정에 따라 링크하는 라이브러리가 결정되었다. 헌데 아래 테이블에 나오는 라이브러리는 단순히 프로젝트 옵션의 컴파일 설정에 의해 결정되는 것이 아니라 Standard C++ library header가 프로그램에 포함되었는지를 보고 링크가 이루어 진다.  

Standard C++ Library

Characteristics

Option

Preprocessor directives

LIBCPMT.LIB

Multithreaded, static link

/MT

_MT

MSVCPRT.LIB

Multithreaded, dynamic link (import library for MSVCP80.dll)

/MD

_MT, _DLL

LIBCPMTD.LIB

Multithreaded, static link

/MTd

_DEBUG, _MT

MSVCPRTD.LIB

Multithreaded, dynamic link (import library for MSVCP80D.DLL)

/MDd

_DEBUG, _MT, _DLL

바로 요 아래에 있는 것이 Standard C++ library header 파일들의 목록이다. 바로 요놈들중에 한놈이라도 프로그램에 선언되어 사용되는 놈이 있다면 위의 테이블에 나온놈들중에서 현재 프로젝트의 컴파일 옵션에 따라 적당한 라이브러리가 추가로 링크가된다. 

algorithm>

<bitset>

<complex>

<deque>

<exception>

<fstream>

<functional>

<hash_map>

<hash_set>

<iomanip>

<ios>

<iosfwd>

<iostream>

<iso646.h>

<istream>

<iterator>

<limits>

<list>

<locale>

<map>

<memory>

<new>

<numeric>

<ostream>

<queue>

<set>

<sstream>

<stack>

<stdexcept>

<streambuf>

<string>

<strstream>

<utility>

<valarray>

<vector>

 

In addition, the following C++ wrappers are documented:

<cassert>

<cctype>

<cerrno>

<cfloat>

<ciso646>

<climits>

<clocale>

<cmath>

<csetjmp>

<csignal>

<cstdarg>

<cstddef>

<cstdio>

<cstdlib>

<cstring>

<ctime>

<cwchar>

<cwctype>

 

이렇게 표만 잔뜩 늘어 놓으면 재미가 없으니, 예를 보자.

우선 아래 그림을 보면 빈 코드가 컴파일 되었는데 포함된 헤더파일은 오직 stdio.h 밖에 없다. 그리고 아래 Output을 살펴보면 MSVCRTD.lib를 볼수 있는데 이것은 현재 이 프로그램을 /MDd 옵션으로 컴파일 되었기 때문이다.


그렇다면 만약 ctime 부분을 포함시키면 어떻게 될까? ctime은 Standard C++ library header 중의 하나이기 때문에 현재 컴파일 설정인 /MDd에 해당하는 라이브러리인 MSVCPRTD.lib가 포함될까? 정답은 아래 그림속에...


앞서본 그림과 달리 아래 부분에 msvcprtd.lib가 포함되어 있다! 호~이!

posted by 대갈장군
2010. 9. 25. 01:40 프로그래밍/C
우선 역사를 보자. C 언어는 기준이 완성되기 전까지는 Input/Output 기능과 같은 기본 함수를 언어자체적으로 지원하지 않았다. 그것에 불편을 느낀 다수의 사용자들이 모여 지금의 C Standard Library를 작성하게 되었다. 

Unix와 C는 둘 다 AT&T's Bell Laboratories에서 1960년대 그리고 1970년대에 개발되었는데 C 언어가 인기가 높아지고 많은 사람들이 사용하기 시작하면서 호환성 문제가 발생한다. 고로 American National Standards Institute(ANSI)에서 표준을 세우고 규격화하여 내놓은 것이 바로 ANSI C이다. 그리고 이것은 1989년에 완성된어 C89라고 명명되어 졌다. 

그렇다면, C Standard Library는 뭐냐 하면, C Programming 언어에서 사용되는 기본 명령들, 예를 들자면 input/output 및 string 핸들링 함수와 같은 것들을 구현하기 위한 headers와 library routines를 모아놓은 ISO C 기준의 일부분이다. 

즉, 다시 말해서 C Standard Library는 문서에 의해 규정된 '인터페이스 기준'이다. 고로 걍 설명서일 뿐이라는 것. 사실 C Standard Library는 24개의 헤더 파일인데 요 헤더 파일들에는 함수들과 데이터 타입 그리고 매크로등이 들어가 있다. 

이것은 다른 언어 (예를 들자면 자바)에 비교해서 아주 간단한 함수들만 선언된 헤더파일들이다. C Standard Library는 기껏해야 수학 함수, 문자열 함수, 타입 변환 함수 및 파일 입출력, 콘솔 화면 입출력 함수 정도만 명시되어 있다. 고로 C Standard Library는 C++ Standard Template Library와 같은 고급 컨테이너 타입이나 GUI, 네트워킹 툴등의 고급 기능은 전혀 없다.

아래의 목록이 바로 ISO가 명시하는 C Standard Library의 헤더 파일들이다.

ISO C library headers

NameFromDescription
<assert.h> Contains the assert macro, used to assist with detecting logical errors and other types of bug in debugging versions of a program.
<complex.h> C99 A set of functions for manipulating complex numbers.
<ctype.h> Contains functions used to classify characters by their types or to convert between upper and lower case in a way that is independent of the used character set (typically ASCII or one of its extensions, although implementations utilizing EBCDIC are also known).
<errno.h> For testing error codes reported by library functions.
<fenv.h> C99 For controlling floating-point environment.
<float.h> Contains defined constants specifying the implementation-specific properties of the floating-point library, such as the minimum difference between two different floating-point numbers (_EPSILON), the maximum number of digits of accuracy (_DIG) and the range of numbers which can be represented (_MIN_MAX).
<inttypes.h> C99 For precise conversion between integer types.
<iso646.h> NA1 For programming in ISO 646 variant character sets.
<limits.h> Contains defined constants specifying the implementation-specific properties of the integer types, such as the range of numbers which can be represented (_MIN_MAX).
<locale.h> For setlocale and related constants. This is used to choose an appropriate locale.
<math.h> For computing common mathematical functions.
<setjmp.h> Declares the macros setjmp and longjmp, which are used for non-local exits.
<signal.h> For controlling various exceptional conditions.
<stdarg.h> For accessing a varying number of arguments passed to functions.
<stdbool.h> C99 For a boolean data type.
<stdint.h> C99 For defining various integer types.
<stddef.h> For defining several useful types and macros.
<stdio.h> Provides the core input and output capabilities of the C language. This file includes the venerable printffunction.
<stdlib.h> For performing a variety of operations, including conversion, pseudo-random numbers, memory allocation, process control, environment, signalling, searching, and sorting.
<string.h> For manipulating several kinds of strings.
<tgmath.h> C99 For type-generic mathematical functions.
<time.h> For converting between various time and date formats.
<wchar.h> NA1 For manipulating wide streams and several kinds of strings using wide characters - key to supporting a range of languages.
<wctype.h> NA1 For classifying wide characters.



posted by 대갈장군
2010. 9. 11. 00:20 카테고리 없음
얼마전 미국의 마약 단속반 직원 몇명이 멕시코에서 마약 갱들에 의해 보복살해 당한 일이 있었다. 기억은 잘 안나지만 세네명이 죽은 것으로 알고 있다.

미국은 사체를 수습해 신속하게 미국 본토로 데려왔고 오바마 대통령은 사체가 도착할 때 미리 공항에 나가서 거수 경례를 하며 죽은 '영웅'들을 맞이했다. 

그 사진을 보는 순간 여러가지 생각이 교차했다. 마치 오바마 대통령은 그들에게 당신들의 죽음을 헛되지 않게 하겠다고 그리고 또 기억하겠다고 말하는 것 같았다. 

우리나라는 '영웅'이 되기 힘들다. 왜일까?

우선 사람들의 기준이 높다. 1등만 기억하는 더러운 세상이라는 유행어가 괜히 생긴게 아니다. 고로, 우리는 칭찬에 인색하다.

반면 손가락질에는 능숙하다. 연예인, 국회의원등 공인들에게 적용되는 잣대는 매우 엄격하며 작은 헛점도 큰 뉴스 거리가 된다. 사람들은 '쯧쯧, 저럴 줄 알았다.. 깨끗한 놈은 하나도 없구만...' 하게 된다.

결국 그런 과정의 반복은 우리 사회 전반에 걸쳐 '불신'으로 나타난다. 누군가가 무엇인가를 잘했다고 해도 일단 의심부터 하게 되는 것이 사실아닌가?

우리는 '선택적 진실'을 즐긴다. 내가 자주 보는 뉴스 사이트는 정해져 있다. 모든 뉴스는 그 사이트를 통해 읽는다. 이미 나는 선택을 한것이다. 그리고 우리는 '튀는 것'을 싫어한다. 관심있는 뉴스를 본 후 추천순으로 정렬하여 가장 추천을 많이 받은 글을 '진실에 가까운 것'으로 받아들인다. 사실 이 과정의 시작부터 우리는 진실을 선택한 것이다. 

우리 스스로에 물어보자. 나는 나에게 얼마나 엄격한 기준을 적용하는가? 그와 같은 기준을 남들에게도 적용하는가? 나는 누군가가 어떤일을 했다면 의심부터 하는가 아니면 칭찬부터 하는가?

부풀려진 '영웅'으로 인해 역효과도 발생하지만 무조건적인 '의심'으로 인해 사회에 걸쳐 나타나는 '불신'보다는 낫다고 생각한다.
최소한 영웅을 좋아하는 사회는 '불신'보다는 '칭찬'을 먼저 하기 때문이다.



posted by 대갈장군
2010. 9. 4. 00:00 프로그래밍
이 내용은 http://www.intowindows.com/how-to-install-windows-7vista-from-usb-drive-detailed-100-working-guide/ 를 참조해서 작성했습니다.

XP에서 XP설치 USB를 만드는 방법은 이미 전에 소개한 바 있으나 Windows 7과 비스타를 설치하는 방법은 조금 다르다. 

우선 작업을 시작하기 전에 필요한 것들을 살펴보면,
  • 최소 4GB 용량을 가지는 USB 
  • 윈도우 7 또는 윈도우 비스타 설치 파일 (DVD를 가지고 있다면 OK)
  • 메인보드가 USB 부팅을 지원해야 함
위 조건을 충족한다면 다음 순서대로 명령수행 해 봅시다~

1. USB 키를 멀쩡한 컴퓨터에 꼽고 안에 들어있는 내용을 비운다.

2. Command Prompt를 열기 (단, 열때 Administrator 권한을 열어야 함)
    Start menu -> All Programs -> Accessories 에 보면 Command Prompt가 있고 우클릭하면 Run as administrator 옵션 있음.

3. 열린 Command Prompt에 DISKPART 라고 치고 엔터 날리기


   그러면 위 그림 아래 부분처럼 DISKPART> 프롬프트가 뜰것임. 그런 다음 LIST DISK 라고 치고 엔터 날리면 현재 이 컴퓨터에 
   연결되어 있는 모든 드라이브 정보가 나오는데 그것들 중에 아까 꼳은 USB 드라이브 정보도 있다.
   그 녀석의 DISK 번호가 무엇인지 잘 기억해 두자.

4. 만약 꼳은 USB의 번호가 Disk 1 이라고 가정하고 아래 명령을 차례대로 수행하자
   SELECT DISK 1
   CLEAN
   CREATE PARTITION PRIMARY
   SELECT PARTITION 1
   ACTIVE
   FORMAT FS=NTFS
   ASSIGN
   EXIT

   위의 명령중 FORMAT FS=NTFS를 실행하면 포멧한다고 시간이 좀 걸린다. 


   위 그림을 보면서 따라하면 더 쉽겠죵

5. 준비해둔 윈도우 7 혹은 비스타 DVD를 CD 드라이브에 넣고 CD 드라이브의 이름을 확인한다. 일반적으로 CD 드라이브는 D 드라이브죠.
    그리고 USB의 드라이브 이름도 확인한다. 내 컴퓨터를 열면 USB의 드라이브 이름을 확인할 수 있다. 여기서는 H라고 가정하자.

6. 아까 열었던 Command Prompt에서 다음 명령을 넣자

    D: CD BOOT
   CD BOOT
    여기서 D:가 바로 윈도우 설치 시디가 들어가 있는 CD 드라이브를 의미한다. 만약 자신의 컴퓨터의 CD 드라이브가 D가 아니라면 바꿔주세용.

7. 마지막으로 다음 명령을 날려준다. 다만 마지막에 들어간 H: 는 현재 자신의 USB 드라이브 이름이므로 자신에게 맞게 바꿔주시길.

    BOOTSECT.EXE /NT60 H:
   

8. 이제 CD 드라이브에 있는 윈도우 7이나 비스타를 모조리 USB로 복사하자. Ctrl+A, Ctrl+C, Ctrl+V! 붙여넣기 콤보 발사

9. 마지막으로 윈도우를 설치할 컴퓨터의 BIOS 셋업에 들어가서 (컴퓨터 시작시 Del 키나 F2 또는 F10, F11 키를 눌러서 들어감) 부팅 순서에서 USB를 최상위로 맞춰놓고 컴퓨터에 USB를 꼽아준 다음 재부팅 시키면 알아서 설치를 시작할 것이다.

종종 일부 노트북은 UBS가 컴퓨터에 연결되어 있지 않은 경우 BIOS의 부팅 순서 설정에 UBS를 보여주지 않는 경우가 있다. 그런 경우를 방지하려면 USB를 꼳아 놓은 상태에서 BIOS를 들어가면 될것이다. Good Luck!
  
posted by 대갈장군
prev 1 2 3 4 5 6 7 8 ··· 16 next