인터뷰에서이 코드를 발견했습니다."ptr을 ptr로"ptr을 명시 적으로 캐스팅합니다.
int main()
{
int **p;
p = (int **) new int(7);
cout<<*p;
return 0;
}
* p에서 런타임 오류가 예상됩니다. 그러나 코드를 실행하면 "0x7"출력으로 성공적으로 실행됩니다. 누군가가 어떻게 작동하는지 설명해 주시겠습니까? 감사.
인터뷰에서이 코드를 발견했습니다."ptr을 ptr로"ptr을 명시 적으로 캐스팅합니다.
int main()
{
int **p;
p = (int **) new int(7);
cout<<*p;
return 0;
}
* p에서 런타임 오류가 예상됩니다. 그러나 코드를 실행하면 "0x7"출력으로 성공적으로 실행됩니다. 누군가가 어떻게 작동하는지 설명해 주시겠습니까? 감사.
여분의 제약 사항이없는 한 정답은 입니다. 위의 내용 중 하나가 아닙니다.입니다. 기본적으로 코드는 int
을 할당하고 해당 메모리를 int*
(마치 reinterpret_cast
) 인 것처럼 해석합니다. 첫 번째 문제는 reinterpret_cast
되고, 결과는 일반적인 경우에 지정되지 않은이며, int
의 크기가 int*
의 크기보다 작은 경우 결과는 당신이로 정의되지 않은 동작입니다 (64 비트 아키텍처를 생각한다)이다 new
호출에 할당 된 크기 이상으로 읽는 것.
int (32 비트)를 int * (64 비트)로 변환하면 결과가 64 비트로 확장됩니다. – gulyan
@gulyan 그러나이 경우 컴파일러는 그런 종류의 캐스트를 수행해야한다는 것을 모릅니다. 일어나는 유일한 캐스트는 위의 줄에서 int *에서 int **까지입니다! –
@gulyan : 아니요, 32 비트 정수에서 64 비트 정수까지'static_cast'에서 컴파일러는 크기를 확장하는 변환을 수행 할 것입니다. 그러나'reinterpret_cast'에서 코드는 * 메모리를 재 해석한다. 즉, 그것은'int'에 포인터를 가져다가 다음 64 비트 (8 바이트)를'int * '처럼 읽습니다. 이것은 정의되지 않은 동작입니다. C 스타일 캐스트의 가장 큰 문제점 중 하나입니다. 명시 적 C++ 캐스트만큼 명확하지 않습니다. –
당신은 새로운 INT를 생성하고 값 7
포인터로 캐스트가보다int *x = new int(7);
당신을 (예를 들어, 메모리 주소 (7)에는 0x07)
int **p = (int**) new int(7);
그런 다음이 주소를 표시와 함께 초기화 한마디.
*p is equal to (int*)7
그것은 제
이것은 코드가 정확한지, 아니면 적어도 모든 상황에서 동일한 출력을 생성하는지, 그렇지 않은지를 나타내는 것 같습니다. 'p'의 역 참조는 정의되지 않은 행동을 일으킨다. –
new int(7);
그 값 7
이며 포인터를 리턴하는 int
메모리를 할당 포인터 값이다.
int **p = (int **) new int(7);
은 해당 메모리를 int**
으로 해석하도록 지시합니다.
cout << *p;
어드레스
*p
에서
int *
출력하는 값이다 컴파일러 말한다. 값은
0x07
입니다. (주소로
7
을 처리합니다). 추가 참조가 발생하면 충돌이 발생합니다 (정확하게는 정의되지 않은 동작).
코드가 이미 정의되지 않은 동작이므로 ... 추가 역 참조를 수행 할 필요가 없습니다. –
@Luchian Grigore : 고마워. 도움이된다 – CppLearner
int main()
{
int **p; // declare pointer to pointer called p
p = (int **) new int(7); // new allocates integer initialized to value of 7 and returns a pointer. Cast the pointer to a point to pointer. p now represents a pointer to a pointer with contents of 0x7. If you called **p you would get the contents at address 0x7.
cout << *p; // dereference p, this yields a pointer, which is an int of value 0x7.
}
이 질문은 귀하의 포인터 지식을 테스트 할 가능성이 가장 높지만 매우 실용적이지는 않습니다.
int main()
{
int **p = (int **) new int(7);
cout << *p;
}
그래서, new int(7)
메모리 sizeof(int)
바이트를 할당하고 그것에 대한 포인터를 반환한다. 메모리가 주소 X에 있다고 가정 해 봅시다. 그러면 X는 (int**)
으로 캐스팅되어 p
에 저장됩니다.
*p
는이 어드레스로 int*
X
에서 int
값 7 intreprets 의미의 int**
역 참조.항상 정의되지 않은 동작에 관계없이 데이터 유형 및 임의의 reintrepretation -
sizeof(int*)
경우는 int*
가 new
할당 버퍼 넘어 판독되므로 다음 읽기 sizeof(int)
보다 크다.
는 같은 크기 인 경우, CPU가 int*
로 정수 (7)를 포함하는 메모리를 읽을 시도합니다 - 이것은 일반적으로 값 int*(7)
를 얻을 것이다, 그러나 표준 5.2.10.5보고 :
일체형 또는 열거 형 값은 명시 * 는 [각주 포인터로 전환시킬 수있다 값이 0 인 다른 표현식을 변환하면 널 포인터가 필요하지 않습니다. --- end foonote] 충분한 크기의 정수로 변환 된 포인터 (구현에 그러한 포인터가있는 경우)와 같은 포인터 유형으로 되돌아 오는 포인터는 원래 값을 갖습니다. 포인터와 정수 사이의 매핑은 달리 구현 정의됩니다.
따라서 정수 값은 포인터 값 (정의되지 않음)으로 변환되지만 값은 구현 정의됩니다. 여전히 되돌릴 수있는 작업 인 것은 일 가능성이 높습니다.int
7은 값이 7 인 int*
이고 결과는 "7"로 표시되는 동작을 설명합니다.
int
크기보다 작은 경우, 그것은 int
값의 조각을 읽고 포인터로 그 해석됩니다. 엔디안에 따라 슬라이스는 0 또는 7 또는 심지어 다른 것일 수 있지만 다시 int
으로 표시되므로 포인터 값으로 변환 할 수 있어야합니다.
무엇을하려하십니까? 엄지 손가락의 기본 규칙은 당신이 캐스팅해야한다면, 당신이 잘못하고 있다는 것입니다. 'new int (7)'이'int *'를 돌려주기 때문에, 당신은 캐스팅해야했습니다. 그러나 형 변환은 코드를 올바르게 만들지 못합니다. 당신이 틀렸다고 사실을 기록한 것뿐입니다. 캐스트를 제거하고 거기에서 작업하십시오. –
@ Davidid : 코드는 아마도 인터뷰에서 나온 것이지 OP에서 나온 것이 아닙니다. – Vlad
@ David Heffernan : 이것은 필기 시험의 면접 질문입니다. 4 개의 옵션으로 컴파일 타임 오류, 런타임 오류, 코드가 정상적으로 실행되며 위에 해당하지 않습니다. 그러한 인터뷰 질문으로 어떤 종류의 지식을 얻으려고하는지 이해하지 못합니다. – CppLearner