2012-06-10 2 views
3

이 코드에서 sizeof(x)은 크기가 x이 아닌 포인터의 크기가 왜됩니까?sizeof (type)가 형식 자체의 크기가 아닌 포인터 크기 인 이유는 무엇입니까?

typedef struct { 
    ... 
} x; 

void foo() { 
    x *x = malloc(sizeof(x)); 
} 
+2

당신의 질문은'malloc'과는 아무런 관련이 없습니다. 약간의 온건성을 가진 질문은 "x"는 무엇입니까? " –

+0

@JensGustedt : 글쎄요, 그렇습니다. 그러나'sizeof' *는 대부분 'malloc'과 함께 사용되지 않습니까? – thejh

+0

'sizeof'와는 아무런 관련이 없습니다. 귀하의 질문에 "x 란 무엇입니까?" 또는 더 명확하게 "여기서 두 가지'x' 중 형식 또는 포인터 변수를 얻었습니까?" –

답변

6

C는 말한다 때문에 :

(C99, 6.2.1p7) "Any other identifier has scope that begins just after the completion of its declarator."

그래서 예에서, 객체의 범위가 바로 x *x 후 시작 x :

x *x = /* scope of object x starts here */ 
     malloc(sizeof(x)); 

이 자신을 설득 유형 x의 또 다른 목적 선언을 넣으려면 객체의 선언 바로 다음에 x : 컴파일 오류가 발생합니다.

void foo(void) 
{ 
    x *x = malloc(sizeof(x)); // OK 
    x *a; // Error, x is now the name of an object 
} 

그렇지 않으면 Shahbaz 피고인이 다른 대답의 의견으로, 이것은 여전히 ​​malloc의 올바른 사용법이 아닙니다. 이 같은 malloc 호출해야합니다 :

T *a = malloc(sizeof *a); 

등을하지

T *a = malloc(sizeof a); 
5

sizeof(x) 포인터이다 x의 최 정의를 사용하기 때문이다. 이. 제를 피하려면 유형 W 변수에 동일한 이름을 사용하지 마십시오.

+5

또한 malloc을 사용하면 다음과 같이 사용하십시오 :'malloc (sizeof (type)) 대신'type * var = malloc (sizeof (* var));' – Shahbaz

+0

Shahbaz 권장 이유는 유형 'var'의 값은 바뀔 수 있고 당신의 코드는 여전히 정확할 것입니다. 'var *'대신'type'을 사용하면 선언에서'type'을'sizeof'에서 변경하는 것을 기억해야합니다. –

0

(뿐만 아니라 프로그래밍에) 여러 가지 서로 다른 이름을 부여하지 않는 것이 나쁜 생각 :

학술 이유 행동 관찰자는 친애하는 동료 주석가들에 의해 이미 언급되었습니다. (: 변수 유형과 변수 인스턴스 여기에) : 투명주고

는 이름 diffenet의 전혀 다른 일을 조언

typedef struct { 
    ... 
} X; 

void foo() { 
    X *x = malloc(sizeof(X)); 
} 

이보다 더 유연 (이미 Shahbaz의 의견에 의해 언급 한) 것이 예제를 코딩하는 방법 :

typedef struct { 
    ... 
} X; 

void foo() { 
    X *x = malloc(sizeof(*x)); 
} 

후자의 예는 할당을하고있는 코드를 변경하지 않고 x의 유형을 변경할 수 있습니다.

이 접근법의 단점은 컴파일러에서 알리지 않고 배열을 참조하고 vica를 (verb) (x의 형식으로) 전환 할 수 있고 코드를 중단 할 수 있다는 것입니다.