malloc관련 질문입니다.
#include
#include
void function(int*);
int main()
{
int m=0;
int val;
int size=5;
int *arr = (int*)malloc(sizeof(int)*size);
while(1)
{
if(m==size)
{
size = size+3;
function(arr);
}
else
{
printf("number ?:");
scanf("%d",&val);
if(val == -1)
break;
(*(arr+m)) = val;
m=m+1;
}
}
for(int i=0;i
printf("%d,",*(arr+i));
}
void function(int *a)
{
printf("a address: %d\n", &a);
int *temp=(int*)malloc(sizeof(a)/sizeof(int)+3*sizeof(int));
for(int i=0;i
*(temp+i) = *(a+i);
a=temp;
}
열혈 강의에 나와 있는 예제를 제 나름대로 풀어 본 것인데요.
배열을 초기에 크기가 5로 설정했다가 더 많은 수의 입력이 들어오면 배열의 크기를 3씩 늘려서 수를 입력하는 소스입니다.
제가 작성한 코드는 잘못된 코드라고 생각이 드는데요.
이렇게 하면 function 함수에서의 a와 main함수에서의 arr이 포인터 입장에서 call by value가 되어 a는 크기가 커진 배열을 가리키지만 arr은 그대로입니다.
그러나 이 코드를 실행하면 a도 기존의 5 크기보다 더 많은 수의 수를 입력받게 됩니다. 즉 malloc으로 할당 받은 것들보다 더 많은 수의 입력이 가능하다는 것은 function함수의 영향이 있었다는 의미 같은데요.(실제로 function함수 없애먼 컴파일이 되지 않습니다.)
분명 잘못된 코드인데 실행이 되는 이유가 무엇일까요?
보통 C에서는 문법상에서 보장되지 않는 것을 하면
보통 C에서는 문법상에서 보장되지 않는 것을 하면 '정의되지 않은 동작'을 합니다.
즉, 이경우 잘 되는것은 단순히 '운이 좋아서'입니다.
5억번 실행해도 잘되더라, 그래도 그건 운이 좋아서입니다.
뭐가 어떻게 돌아가길래 잘되는지를 알고 싶다면 컴파일러 소스코드를 뜯어볼수도 있고, 구현명세를 찾아볼 수도 있겠지만,
그건 컴파일러의 작동원리를 공부하는게 아니라면 쓸모없는 짓입니다.
정의되지 않은 동작이기 때문에 이러한 동작은 컴파일러에 따라서도 다를수 있고, 같은 컴파일러여도 다를수도 있습니다.
어떤 컴파일러는 일관되게 정의되지 않은 동작에 대해서 컴퓨터를 과부하 시켜서 박살내버리게 구현되어있을 수도 있습니다.
댓글 달기