2010-06-02 2 views
0

명시 유형 :나는이 지정하는 책에서 읽은 변환

//: C03:SimpleCast.cpp 
int main() { 
int b = 200; 
unsigned long a = (unsigned long int)b; 
} ///:~ 

"캐스팅은 강력하지만 일부 상황에서 데이터가있는 것처럼 취급하도록 컴파일러에 강제 있기 때문에 (두통을 일으킬 수 있습니다인스턴스의 경우)보다 큰 경우 메모리에서 더 많은 공간을 차지하므로 다른 데이터를 위태롭게 할 수 있습니다. 위의 과 같은 간단한 캐스트를 만들 때가 아니라 포인터를 캐스팅 할 때 대개 이 발생합니다.

이제 캐스팅 포인터가 다른 데이터를 짓밟을 수있는 예제를 제공해 주시겠습니까?

+3

C++에서는 C- 캐스트 대신 C++ 캐스트를 사용하는 것이 좋습니다. –

답변

5
int main(void) 
{ 
    short int a = 5; 
    short int b = 7; 
    *(long int*)&a = 0; 
} 

sizeof(long) > sizeof(short) 가정, 컴파일러 가정하면 b 전에 스택 a두고, b 휴지통으로한다. C 스타일 캐스트를 통해

+2

컴파일러가 a 앞에 스택에 b를 넣으면 반환 주소 나 호출자의 저장된 프레임 포인터와 같은 다른 항목이 휴지통으로 표시됩니다. –

+2

b는 휴지통이 될 수 있습니다. 당신이 한 것은 reinterpret_cast입니다 (항상 말했듯이 이것이 C++ 캐스트를 사용해야하는 이유이며, 그래서 당신이하는 일을 알고 있습니다). 이를 역 참조하면 UB가 발생합니다. 게다가, b가 a 뒤에 오더라도 & b == & a + sizeof (a)는 보장 할 수 없습니다. –

+0

@ 노아 : 예, 제가 소홀히 한 몇 가지 다른 가정이 있습니다. 그러나 개념은 분명해야합니다 ... –

1
int main() { 
    char a[] = "This is a string."; 

    *(long *)a = 12345678; // will typically overwrite first four or eight bytes of a. 

    std::cout << a; 
    return 0; 
} 
+0

하지만 다른 * 데이터는 휴지통으로 처리되지 않습니다. –

+0

@Oli : 예, 아니요. 배열의 시작 주소를 사용하고 첫 번째 바이트가 아닌 다른 바이트를 덮어 씁니다.아마도 'a'대신에'& a [0]'을 사용하면 더 분명 할 것입니다. 그러나이 두 가지는 똑같은 것을 의미합니다. –

+0

아 그래,이게 사실이라고 생각해. 배열을 "원자"라고 생각하는지 여부에 달려 있습니다! –

0
char unix[5]="unix"; 
char* first= &(unix[0]); 
int * intptr= (int*) first; 
*first=64; 
printf("%s\n",unix); /* prints @ /* 
0

이 C++이 아닌 C로 태그 된 이후, 나는 또한 C에서 최대 읽어 보시기은 ++ 스타일 캐스트 :

static_cast<Derived *>(pBase)->DMethod(); 
if (dynamic_cast<Derived *>(pBase)) dynamic_cast<Derived *>(pBase)->DMethod(); 
const_cast<CRect &>(constRect).x = 3; 
int *pInt = reinterpret_cast<int *>(charbuff); 

내가보기 엔 스콧 마이어의 책 효과적인 C를 추천 ++, 55 프로그램과 디자인을 개선하기위한 특정 방법, 제 3 판. 제 2 판에서도 C++ 스타일 캐스트를 다룰지라도 제 3 판을 얻으십시오.

기본적으로 C++을 사용하고 있고 컴파일러가 지난 10 년 이내에 작성된 경우 C 스타일 캐스트를 사용하지 마십시오. C++ 스타일 캐스트 사용.