컴퓨터공부/C & C++ & STL

Cfaq 6

achivenKakao 2009. 4. 5. 01:18

Q 7.29 (질문 6.14를 따라서) 배열을 동적으로 할당한 다음, 이 배열의 크기를 바꿀
수 있을까요?
Answer 물론입니다. realloc이 바로 그 역할을 해 주는 함수입니다. (예를 들어,
질문 6.14에 나온 것처럼 dynarray) 동적으로 할당된 배열의 크기를 바꾸
려면 다음과 같은 코드를 씁니다:
dynarray = (int *)realloc((void *)dynarray,
20 * sizeof(int));
realloc이 항상 메모리 블럭의 크기를 늘리는데 쓰이는 것은 아닙니다.
realloc은, 가능하면, 전달받은 인자와 같은 포인터 값을 돌려주지만, 요
청한 크기에 맞게 메모리 블럭을 다시 찾을 경우에는, 인자로 전달된 포인
터 값과는 다른 값을 돌려줍니다. 이 경우, 인자로 전달된 포인터 값은 더
이상 쓸 수 없습니다.
만약 realloc이 요청한 메모리 공간을 찾지 못했다면, 널 포인터를 리턴
합니다. 이 때, 인자로 전달되었던 메모리는 (realloc을 부르기 바로 전
상태로) 그대로 유지됩니다.
realloc을 써서 메모리의 크기를 변경했을 경우에, 다른 포인터가 이 메
모리 공간을 가리키고 있었는지 (“alias”라는 용어를 씁니다) 주의해야 합
니다: 만약에 realloc이 다른 곳에 메모리 블럭을 할당했다면, 다른 포인
터들도 값이 올바르게 바뀌어야 합니다. (malloc의 실패 여부를 확인하지
않았다는 단점이 있긴 하지만) 누군가가 제공한 코드입니다:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *p, *p2, *newp;
int tmpoffset;
p = malloc(10);
strcpy(p, "Hello,"); /* p is a string */
p2 = strchr(p, ','); /* p2 points into that string */
tmpoffset = p2 - p;
newp = realloc(p, 20);
if (newp != NULL) {
p = newp; /* p may have moved */
p2 = p + tmpoffset; /* relocate p2 as well */
strcpy(p2, ", world");
}
printf("%s\n", p);

 

위와 같이 기본값(base)을 기초로 해서 포인터 값을 다시 계산하는 것이
바람직합니다. 다른 방법은.두 값의 차(difference)인 newp - p의 값을 기
초로, realloc을 부르기 전, 후의 베이스 포인터의 값을 쓰는 방식. 동작
한다고 보장할 수 없습니다. 왜냐하면, 포인터 뺄셈은 같은 오브젝트를 가
리키는 포인터 사이에서만 의미가 있기 때문입니다. 덧붙여 질문 7.12, 7.30
도 참고하시기 바랍니다..

note. 그러나 어떤, ANSI 이전의 컴파일러에서는 realloc이 실패했을 경우, 인자로 전달되었던 메모
리 블럭의 보존 여부를 보장하지 않습니다.