:: 게시판
:: 이전 게시판
|
이전 질문 게시판은 새 글 쓰기를 막았습니다. [질문 게시판]을 이용바랍니다.
통합규정 1.3 이용안내 인용"Pgr은 '명문화된 삭제규정'이 반드시 필요하지 않은 분을 환영합니다.법 없이도 사는 사람, 남에게 상처를 주지 않으면서 같이 이야기 나눌 수 있는 분이면 좋겠습니다."
08/03/26 17:29
이런 상황에서 a, b, c가 연속된 메모리에 저장된다는 보장은 없으니까,
dr[0][0], dr[1][0], dr[2][0] 말고 다른 배열값은 뭐가 나올지 알 수 없고 (컴파일러 맘대로...), 접근해서도 안됩니다. (잘못하면 access violation이 나올지도 몰라요.)
08/03/26 17:37
double a,b,c로 스택 내에 메모리 선언하면 주소가 각기 a=12, b=8, c=4 식으로 앞쪽 것이 뒤에, 뒤쪽 것이 앞에 선언됩니다.
그러므로 (&a)+4 = &b가 돼겠죠. dr[0][0] = &a 입니다. dr[0][-1] = &b 입니다. 그러므로 dr[1][0] = &b 입니다. dr[1][1] = &a입니다.
08/03/26 17:38
위에서 말씀하셨듯, 저 상황을 유도하는거 자체가 위험한 일이긴 합니다. 컴파일러나 머신마다 다를 수 있으니.(컴파일러는 그렇게 상관있을거 같지 않아도 CPU는 좀 관련 많을거 같군요)
08/03/26 17:46
결론적으로 말하자면, compiler가 stack에 a, b, c를 순서적으로(오름 차순이건 내림 차순이건) 할당하기에 그렇습니다. 때문에 &b를 dr[1]에 할당하면, dr[1][1] => *(dr[1] + 1) => *(&b + 1) => stack 증가 방향에 따라 a 혹은 c가 대응... 이런 겁니다.
조금 더 상세하게 설명하면, 원론적으로 볼 때 위 program은 pointer와 배열을 조금 혼동해서 (잘못) 사용한 경우입니다. 즉, dr은 pointer의 배열로 선언을 했는데 각 원소, 즉 각각이 pointer인 d[0], d[1], d[2]에 값을 줄 때 하나의 변수의 주소 - 각각 &a, &b, &c를 주었다면, 사용시 원칙적으로 *dr[0], *dr[1], *dr[2]로만 이용하는 것이 옳습니다. dr[0][0] 이 문법적으로 그리고 결과적으로 *dr[0]과 같기는 하지만, 이렇게 사용하려면 애당초 값을 줄 때 배열의 주소를 주던지, 아니면 malloc이나 비슷한 memory allocation 류의 function을 써서 어쨌거나 결과적으로 배열의 주소를 가리키도록 해서 사용하는 것이 옳습니다. 예를 들어 double SOME[10]; 이 선언이 되어 있다면, dr[0] = SOME; 혹은 dr[0] = &SOME[0]; 혹은 dr[0] = &SOME[3]; 이런 식으로 값을 준 후에야 dr[0][n]이 의미를 갖는 거죠. 물론 이 경우도 n이 배열 안이어야 하는 거구요. n이 배열의 크기를 넘어가면 실제로 무엇을 가리킬지는 상황에 따라 다릅니다. core dump될 수도 있고, 아니면 program이 죽지는 않고 위와 같은 현상을 보여줄 수도 있고... 어쨌거나 원론적으로는 bug입니다. PS) 뒤늦게 김연우님의 답변을 보고 제 답변과 숫자에 차이가 있어서 혹 의문을 가지실까봐 뱀 다리를 답니다. *(&b + 1)에서의 1은 그 다음 원소라는 의미로, 실제 주소 계산에서 1로 번역되는 것이 아닙니다. 즉, 본 예제의 경우에서 pointer의 대상이 double인 바, double이 4byte를 사용하기에 실제 주소 계산(assembly level)에서는 4로 계산되죠.
08/03/26 19:29
제대로 배우기 시작한지 1달좀 지났네요..
답변 너무너무 감사하고여.. dr[0][0]과 *dr[0]이 같다라는걸 알려주기위한 코드였기 때문에 혼동(잘못)해서 사용한건 아니에요. 감사합니다.. 자세한 답변에 질문에 궁금증이 해결되었네요.^^
|