2009-06-04 3 views
51

명시 적으로 malloc()의 반환 값을 캐스팅해야합니까?

다음 경우에 대해 물어보고 싶었습니다 : malloc
char *temp; 
temp = malloc(10); 

malloc의 반환 유형이 void*이므로 malloc에 의해 반환 된 포인터는 임시로 할당되기 전에 char* 유형으로 암시 적으로 캐스트됩니까? 이와 관련하여 표준이 무엇이라고 말합니까?

포인터 변수가 다음과 같은 구조체 유형 인 경우 :

struct node *temp; 
temp = (struct node *)malloc(sizeof(struct node)); 

struct node* 유형으로 캐스팅하지 않고 temp에 메모리를 할당하면 struct node* 유형으로 암시 적으로 캐스팅되거나 명시 적으로 캐스팅해야합니다 그것 struct node* 유형?

+7

C 컴파일러 대신 C++ 컴파일러로 코드를 컴파일해야하는 경우 캐스팅이 필요합니다. 결과적으로, 순수한 C는 그것을 필요로하지 않지만, 대부분의 코드에는 명시 적 캐스트가 포함됩니다. 나는 대개/* = C++ = * /로 그 이유를 나타내는 태그를 붙입니다. –

+0

비록 필요하지는 않지만 나에게 약간의 자세한 정보가 담긴 코드를 나중에 읽도록 ​​도와줍니다. – Xolve

+2

[이 질문] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858)도 참조하십시오. – unwind

답변

33

C의 void 포인터는 명시 적 캐스트가없는 모든 포인터에 할당 할 수 있습니다.

+9

함수 포인터에 적용되지 않는다고 생각합니다. –

+11

C는 함수 포인터를 함수 포인터가 아닌 포인터로 캐스트 할 수 있는지 여부를 불문하고 정의하지 않습니다. C++이이를 명시 적으로 금지하고 있으며 C++ 1x가 조건부로이를 지원합니다. –

+10

그리고 POSIX (2008 이상)에서는 함수 포인터가 데이터 포인터와 동일한 크기 여야합니다. –

10

C는 void*에서 암시 적으로 변환되므로 캐스트가 자동으로 수행됩니다. C++에서만 변환 ~void*은 암시 적으로 수행되며 다른 방향으로는 명시 적 형 변환이 필요합니다.

+2

참고 C++에서는 형변환없이 void * 로의 변환을 지원합니다. –

3

C++에서 명시 적으로 캐스팅해야하지만, 실제로는이를 수행 할 때 표시되는 언어입니다.
C에서 실제로 캐스팅 할 필요는 없지만 메모리는 단지 메모리 일뿐입니다. 최신 C 표준에서 필요로하는지 확인하기 위해 검색을해야합니다.

+2

C99 표준에는 캐스트가 필요하지 않습니다. –

49

"자신을 반복하지 말 것"이라고 생각하면 malloc() 호출에서 변수 선언에서 유형 이름을 반복 할 필요가 없다는 점이 매력적입니다. 사람들이 지적했듯이, 포인터는 기능 포인터를 제외하고는 손실없이 void *으로 변환하고 변환합니다.

또한이 메모에서 sizeof을 사용하여 반복하지 않아도됩니다. 구조를 할당 할 때 두 번째 예는, 다음과 같이 쓸 수있다 : 내 너무 겸손하지 의견

struct node *temp; 
temp = malloc(sizeof *temp); 

최고의 방법입니다.

반복하는 것을 피하면 작성한 물건의 수를 줄이며, 그 결과 물건의 수를 줄일 수 있습니다.

sizeof 인수의 별표는 "이 포인터가 가리키는 객체의 크기"를 의미합니다. 물론 "struct node"의 크기와 동일하지만 유형 이름을 반복하지는 않습니다. 이것은 sizeof이 (컴파일시!) 해당 인수 인 표현식의 크기를 계산하기 때문입니다. 이 경우. sizeof 3int 표현식의 크기를 계산하는 것처럼 sizeof *tempstruct node의 인스턴스 크기를 계산합니다.

즉 변수 이름 자체를 반복해야하지만 이는 종종 더 간단한 표현이고 올바른 결과를 얻기 쉽고 컴파일러가 오류를 쉽게 찾아 낼 수 있습니다.

+6

+1 sizeof * temp – diapir

+3

이것은 DRY를 적용하는 것이 안전하지 않은 프로그래밍 방법입니다 (다음 링크 참조). 반복을 피하는 것이 오류를 줄인다는 주장은 상황에 따라 다릅니다. 모호함으로 인해 불명예 한 C의 포인터에 관해서는 나쁜 주주로 이어질 것입니다. 오히려 장황하고 컴파일 타임에 (런타임과 반대되는) 문제를 찾기 위해 캐스트를 반복합니다 : https://www.securecoding.cert.org/confluence/display/seccode/MEM02-C.+Immediately+cast+ + 결과 + of + a + memory + 할당 + function + call + into + a + pointer + to + the + allocated + type –

+3

평상시처럼 securecoding.cert.org는 쓰레기로 가득차 있습니다. 또는 더 정중하게 말하자면, 내가 본 사이트에서 읽은 모든 기사는 잘못된 정보로 가득 차 있습니다 ('ftell'과'fstat'를 생각해보십시오), 널리 해롭고 유해한 것으로 동의 된 스타일 및/또는 평범한 것 카고 - 컬트 "보안"프로그래밍. –

관련 문제