2010-08-13 7 views
35

나는 항상 이것에 궁금해했다. 왜 C++에서 반환 값을 malloc에서 캐스팅해야 하나?C++에서 malloc()에 대한 캐스트가 필요하지만 C가 필요하지 않은 이유는 무엇입니까?

가 여기에 작동 C의 예 ++입니다 :

int *int_ptr = (int *)malloc(sizeof(int*)); 

을 그리고 여기에 작동하지 않는 C++의 예 (NO 캐스트)입니다 :

int *int_ptr = malloc(sizeof(int*)); 

내가 들었 C에서, 실제로 malloc()에서 출력을 전송하는 것은 실수입니다.

누구든지이 주제에 대해 의견을 말할 수 있습니까?

+0

C++의 유형이 더 중요하므로 캐스트를 통해 정확한 유형을 지정해야합니다. – Abhay

+9

이것은 귀하의 질문과 직접적인 관련이 없지만 sizeof (int *)가 아닌'sizeof (int)'를 원한다고 생각합니다. 즉,'sizeof * int_ptr'을 사용하는 것이 더 낫습니다. 이것은 int_ptr이 가리키는 어떤 타입의 메모리라도 할당 할 수 있도록 보장합니다. – bcat

+5

왜 C++에서 malloc을 사용하겠습니까? – SoapBox

답변

27

몇 가지 포인트 :

C 무효 포인터가 암시 적으로 다른 개체 포인터 형식으로 변환 할 수 있습니다. C++은 그렇지 않습니다. 당신이 범위 malloc()에 대한 선언이없는 다른 인 stdlib.h 포함하는 것을 잊지 또는 경우에 유용한 진단을 supress합니다 C에서 malloc()의 결과를 주조

. C가 이전 선언없이 함수 호출을 발견하면 함수가 int을 리턴한다고 가정합니다. malloc()에 대한 선언이없고 캐스트를 중단하면 호환되지 않는 유형 (포인터에 대한 int)을 할당하려고한다는 진단을 받게됩니다. 결과를 캐스팅하면 진단 도구가 불충분 해지고 잠재적으로 런타임 문제가 발생합니다. 포인터 값을 int로 변환하고 다시 포인터로 변환하면 유용한 결과를 얻을 수 있다는 보장이 없기 때문입니다.

C++을 작성하는 경우 malloc()free() 대신 newdelete을 사용해야합니다.그래, 네, 사람들이 코드를 C와 C++ 모두로 컴파일해야하는 모든 이유를 들었지만 언어에 적합한 메모리 관리 도구를 사용하면 얻을 수있는 이점이 IMO 두 버전을 유지 관리하는 비용보다 큽니다.

참고 : void * 유형이 C89 표준에 추가되었습니다. 이전 버전의 C는 malloc() return char * 이었으므로 다른 포인터 유형에 결과를 할당하는 경우 해당 버전에서 이 필요했습니다. 거의 모든 사람들이 최소한 C89 표준을 지원하기 때문에 이전 구현 중 하나를 실행하는 확률은 매우 낮습니다.

+4

캐스팅 문제와 상관없이 현대 컴파일러가 malloc() 선언 누락에 대한 경고를 출력하지 않습니까? –

+0

@Daniel : 경고 수준에 따라 다릅니다. 캐스트 경고는 일반적으로 누락 된 선언보다 낮은 경고 수준에 나타납니다. –

+0

어쨌든, 어쨌든 캐스트를 벗어나는 것이 가장 좋습니다. –

7

C는 다른 포인터 유형에 void*에서 암시 적 캐스트를 지원합니다. C++은 그것을 허용하지 않습니다.

명시 적으로 malloc의 반환 값을 캐스팅 C에 따라이 눈살을 찌푸렸다 있다는 이유 중 하나는 malloc 서명이 현재 컴파일 단위에 포함되어 있지 않은 경우, 컴파일러는 반환 형식이 int과의 암시 적 변환이라고 가정하는 것입니다 할당하려는 포인터 유형으로 컴파일하면 즉시 해결할 수있는 컴파일 타임 경고가 표시됩니다. 명시 적 캐스트를 사용하면 실수를하면 경고가 발행되지 않습니다.

13

C++은 강력한 형식의 언어이기 때문입니다. C++에서 암시 적 형변환은 "확장"중인 경우에만 허용됩니다. 즉, 새 유형이 이전 유형이 보유 할 수있는 모든 값을 보유 할 수있는 경우에만 허용됩니다. 더 작은 정수 유형에서 더 큰 정수 유형으로의 변환이 허용됩니다. 모든 포인터 유형에서 void*으로 캐스팅 할 수 있습니다. 서브 클래스에서 슈퍼 클래스로 캐스트하는 것이 허용됩니다. 다른 모든 캐스트는 명시 적으로 만들어야합니다. 컴파일러에게 "내가하는 일을 알고 있습니다. 이것은 실수가 아닙니다."

malloc()은 어떤 것이 든 될 수 있으므로 컴파일러는 캐스트가 성공할 것이라는 (또는 의미가있는) 것을 보장 할 수 없습니다. 명시 적 형변환을 사용하면 컴파일러에게 실제로 수행중인 작업이 의도적임을 나타냅니다.

C, OTOH는 그런 엄격한 캐스팅 규칙을 가지고 있지 않습니다. 당신은 어떤 두 가지 타입 사이에서 행복하게 던질 수 있고, 결과적으로 나쁜 일이 발생하지 않도록 프로그래머가 책임진다.

+6

암시 적으로 'int'를 'bool'에 아무 문제없이 던져 넣을 수 있습니다. – UncleBens

+0

* "C++은 강력한 형식의 언어이기 때문에 그럴 것입니다."* ... 그리고 C는 그렇지 않습니다! – cdhowie

관련 문제