2012-05-10 1 views
1
int test_malloc(void **ptr, size_t size) 
{ 
    (*ptr) = malloc(size); 
    return 0; 
} 

int test_app() 
{ 
    char *data = NULL; 
    int ret = 0; 
    ret = test_malloc((void **)&data, 100); 
} 

컴파일러 : GCC 나는이를 확인 몇 가지 옵션에 의존하고 생각하고, 내가 -O2 & -Wall을 사용하고 중에서도 4.1.2아래의 코드에서 "역 참조 형식의 포인터는 엄격한 별칭 규칙을 위반합니다"& 해결 방법은 무엇입니까?

. 나는이 같은 시도

+0

가능한 복제본 [Dereferencing type-punned 포인터가 엄격한 앨리어싱 규칙을 위반합니다.] (http://stackoverflow.com/questions/3246228/dereferencing-type-punned-pointer-will-break-strict-aliasing-rules) –

+0

또한 'test_app'와 같은 인터페이스를 작성하지 마십시오. 그것은'int'를 리턴하고 당신은 하나를 리턴하지 않고, 어떤 것도 수신하지 않는 불특정 다수의 인수를 받는다. gcc는 반환 값을 알려 주어야합니다. –

답변

3

잘 작동합니다.

이처럼 해결할 수 :

int test_app() 
{ 
    char *data = NULL; 
    void *void_data = NULL; 
    int ret = 0; 
    ret = test_malloc(&void_data, 100); 
    data = (char*)void_data; 
} 

그러나 더 나은이 같은 문제를 방지하기 위해 test_malloc 반환 void*을 확인하는 것입니다.

+0

+1이 이런 추악한 API를 사용하여 코드가 얼마나 추악한 지 보여주는 것입니다. –

1

당신은 유형 char*의 변수를 가지고 있고, test_malloc 당신이 엄격한 앨리어싱 규칙을 나누기 유형 void *의 좌변을 통해 그것을 수정하는

void * test_malloc(int size) 
{ 
    void *mem = malloc(size); 
    if (mem == NULL) 
    { 
     printf("ERROR: test_malloc %d\n", size); 
    } 
    return mem; 
} 

int test_app() 
{ 
    char *data; 
    int ret = 0; 
    data = test_malloc(100); 

    if(data != NULL) 
     free(data); 
} 
2

C에서 수행하려는 작업을 수행 할 수 없습니다. 그것은 잘못된 코드입니다. void *을 사용하여 일반 포인터를 반환하려는 경우 반환 값은이 포인터를 반환하는 유일한 방법입니다. void *이 포인터 유형으로 변환되고 어떤 포인터 유형도 void *으로 변환되지만 void **이 다른 유형의 포인터에 대한 포인터로 변환되지 않으며 void **으로 변환되지 않기 때문입니다.

+0

그리고 저는 잊었습니다 : 표준은'char *'와'void *'가 같은 객체 표현을한다는 것을 보증합니까? 표현이 다르다고 가정하면 변환이 허용되고 엄격한 앨리어스 위반으로 인해 옵티마이 저가 휴지통에 빠지지는 않지만 'test_malloc'에 의해 쓰여진 'void *'를 a로 재 해석 한 이후에는 코드가 작동하지 않습니다. 'char *'는 잘못된 주소를줍니다. –

+0

실제로 나는'void *'가 본질적으로 여분의 자동 변환과 역 참조 또는 산술을 사용하지 않고'char * '의 복사본으로 지정 되었기 때문에 그들이 동일한 표현을 필요로한다고 생각합니다. 그래도 확실히 확인하고 싶을 수도 있습니다. 그래도 그런 식으로 접근하는 것은 여전히 ​​앨리어싱 위반이라고 생각합니다. –

+0

예, 에일리어싱 위반은 이미 쇼 스토퍼에 동의합니다. 나는 동기 부여를 쌓기 위해 노력했다. GCC가 실제로 AFAIK가 아닌 다른 객체 포인터 유형에 대해 서로 다른 표현을 사용하는 것은 아니지만이 표준은 독특한 아키텍처를 허용합니다. 'char *'가 아니고'int *'라면, 역사적인 예가 있을지도 모른다. –