2010년 1월 28일 목요일

구조체 멤버 동적할당(C99)

C99는 탄력적인 배열 멤버라고 불리는 새로운 기능을 가지고 있다. 탄력적인 배열 멤버 기능을 사용해서 프로그래머는 마지막 멤버가 특별한 속성을 가지고 있는 배열인 구조체를 선언할 수 있다. 하나의 특별한 속성은 최소한, 즉각적이지 않은 배열이 존재하지 않는다는 것이다.
두번째 특별한 속석은 정확한 코드를 사용할 경우, 개발자는 탄력적인 배열 멤버가 존재하고 필요한 요소의 ㅅ를 가지고 있는 것처럼 멤버를 사용할 수 있다. 이는 다소 이상하게 들릴수도 있을 것이므로 탄력적인 배열 멤버를 가지고 있는 구조체를 생성하고 만들어보자.

다음은 탄력적인 배열 멤버를 선언하는 규칙이다.

- 탄력적인 배열 멤버는 배열의 마지막 멤버여야 한다.
- 적어도 하나 이상의 다른 멤버가 있어야 한다.
- 탄력적인 배열은 []가 비어있다는 것을 제외하면 일반 배열처럼 선언된다.

※ 예전 C9x를 지원하던 컴파일러들은 지원이 되지 않는다. C99를 지원하는 컴파일러에서 가능하다. "struct hack"라는 90년대 초반에 나타났던 해킹 기법은 배열을 '1'로 초기화 하고 있었다. 그리고 동적 배열 길이를 사용 자로 부터 입력을 받아 처리하던 부분은 문제가 있다.

다음 예제를 보자.

struct flex
{
   int count;
   double average;
   double scores[];    // 이게 바로 탄력적인 배열 멤버
};

struct flex 형식의 변수를 선언한다면, scores에 대해 메모리 공간이 할당되어 있지 않기 때문에 scores를 어떤 것에도 사용할 수 없다. 사실, struct flex형의 변수를 선언하는 것을 의도한 적도 없다. 대신, struct flex형에 대한 포인터를 선언하고 난 후, malloc()을 사용해서 struct flex의 보텅 내용에 충분한 저장 공간을 할당하고 탄력적인 배열 멤버에 원하는 공간을 추가로 할당한다. 예를 들어, scores가 다섯개의 double값이 있는 배열을 나타내 주길 원한다고 가정해 보자. 이경우  다음과 같이 코드를 작성한다.

struct flex * pf;    //포인터를 선언한다.
pf = malloc(sizeof(struct flex) + 5 * sizeof(double));


이제 count, average와 다섯 개의 double값을 저장할 수 있는 충분한 양의 메모리를 갖게 되었다. pf포인터를 사용해서 멤버에 접근할 수 있다.

pf->count = 5;
pf->scores[2] = 19.

멋지군!! ok 다 했으면 반드시 free(pf)를 해줘야 한다는걸 잊지 말길 바란다.

댓글 없음:

댓글 쓰기