programing

C에서는 왜 포인터를 놓기 전에 던질까요?

prostudy 2022. 6. 5. 17:46
반응형

C에서는 왜 포인터를 놓기 전에 던질까요?

오래된 코드 베이스에서 작업하고 있는데 free()를 호출할 때마다 거의 모든 인수에 캐스트를 사용합니다.예를들면,

free((float *)velocity);
free((float *)acceleration);
free((char *)label);

여기서 각 포인터는 대응하는(및 일치하는) 유형입니다.나는 이것을 하는 것이 전혀 의미가 없다고 본다.아주 오래된 코드라서 K&R 같은 건 아닌지 의문이 남아요.이 경우 이전 컴파일러를 지원하고 싶기 때문에 삭제하고 싶지 않습니다.

이 깁스를 사용해야 하는 기술적 이유가 있습니까?나는 그것들을 사용할 실용적인 이유조차 잘 모르겠다.데이터를 해방하기 직전에 데이터 유형을 상기하는 것이 무슨 의미가 있습니까?

편집: 이 질문은 다른 질문과 중복되지 않습니다.또 다른 질문은 이 질문의 특별한 경우인데, 저는 가까운 유권자들이 모든 답을 읽을 수 있다면 분명하다고 생각합니다.

콜로폰:이것이 필요한 진짜 이유이기 때문에 "const answer" 체크 마크를 붙입니다.하지만, 적어도 일부 프로그래머들 사이에서는 ANSI C 이전의 커스텀이라고 하는 답변이 제 경우에 사용된 이유인 것 같습니다.여기 많은 분들이 좋은 점들이 많네요.당신의 노고에 감사드립니다.

포인터가 다음과 같은 경우 컴파일러 경고를 해결하기 위해 캐스팅이 필요할 수 있습니다.const다음은 free 인수를 제시하지 않고 경고를 발생시키는 코드의 예입니다.

const float* velocity = malloc(2*sizeof(float));
free(velocity);

컴파일러(gcc 4.8.3)는 다음과 같이 말합니다.

main.c: In function ‘main’:
main.c:9:5: warning: passing argument 1 of ‘free’ discards ‘const’ qualifier from pointer target type [enabled by default]
     free(velocity);
     ^
In file included from main.c:2:0:
/usr/include/stdlib.h:482:13: note: expected ‘void *’ but argument is of type ‘const float *’
 extern void free (void *__ptr) __THROW;

사용하시는 경우free((float*) velocity);컴파일러가 불평을 멈춘다.

이전 표준 C에는 없었다.void*다만char*전달된 모든 파라미터를 캐스팅해야 했습니다.고대 C 코드를 발견하면 이러한 캐스트를 찾을 수 있습니다.

참고문헌과 비슷한 질문입니다.

첫 번째 C 표준이 출시되었을 때, malloc 및 free의 프로토타입은 malloc 및 free의 시제품에서 변경되었습니다.char*에게void*아직도 가지고 있는 것 같아요

물론 표준 C에서는 이러한 깁스는 불필요하며 가독성을 해칠 뿐입니다.

여기 또 다른 가설이 있다.

이 프로그램은 C89보다 전에 작성되었다고 합니다.즉, 이 프로그램은 C89의 프로토타입과 일치하지 않습니다.free왜냐하면, 그런 것이 없었을 뿐만 아니라const도 아니다void *C89 이전에는 기능 프로토타입이 없었습니다. stdlib.h그 자체가 위원회의 발명품이었다.시스템 헤더가 일부러 선언한 경우free이런 식으로 했을 거예요.

extern free();  /* no `void` return type either! */

여기서 중요한 점은 함수 프로토타입이 없다는 것은 컴파일러가 인수유형체크를 하지 않았다는 것입니다.디폴트 인수 프로모션(바리안트 함수 호출에 적용되는 것과 동일)이 적용되어 이것으로 끝입니다.각 콜 사이트의 주장을 착신측의 기대와 일치시키는 책임은 전적으로 프로그래머에게 있습니다.

하지만, 이것은 여전히 논쟁할 필요가 있었다는 것을 의미하지는 않는다.free대부분의 K&R 컴파일러에 탑재되어 있습니다.와 같은 기능

free_stuff(a, b, c)
    float *a;
    char *b;
    int *c;
{
    free(a);
    free(b);
    free(c);
}

올바르게 컴파일 되어 있어야 합니다.그래서 여기 있는 것은 버그가 많은 컴파일러에 대응하기 위해 작성된 프로그램이라고 생각합니다.예를 들어 다음과 같은 특수한 환경입니다.sizeof(float *) > sizeof(int)그리고 컴파일러는 콜 포인트로 적절한 호출 규칙을 사용하지 않는 한 포인터 규칙을 사용하지 않습니다.

저는 그런 환경에 대해 전혀 알지 못하지만 그렇다고 해서 그런 환경이 없었던 것은 아닙니다.1980년대 초 8비트 및 16비트 마이크로용 "타이니 C" 컴파일러가 가장 유력하게 떠오릅니다.초기 크레이가 이런 문제를 겪었다는 사실도 놀랍지 않을 것이다.

오래된 이유: 1.사용방법free((sometype*) ptr), 포인터를 의 일부로 간주할 필요가 있는 타입에 대해서는, 코드가 명시되어 있습니다.free()명시적 캐스트는, 다음의 경우에 도움이 됩니다.free()(Do-it-Resign)로 대체됩니다.DIY_free().

#define free(ptr) DIY_free(ptr, sizeof (*ptr))

A DIY_free()(특히 디버깅모드에서) 해방된 포인터의 런타임 분석을 실행하는 방법이었습니다.이것은 많은 경우,DIY_malloc()credential, 글로벌 메모리 사용량 카운트 등을 추가합니다.우리 팀은 더 현대적인 도구가 등장하기 전에 이 기술을 몇 년 동안 사용했습니다.그것은 free'd가 유형으로 주조된 항목이 원래 할당되었다는 것을 의무화했다.

  1. 메모리 문제 등을 추적하는 데 오랜 시간이 걸리기 때문에 type free'd를 캐스팅하는 등의 작은 트릭을 사용하면 디버깅을 검색하고 좁힐 수 있습니다.

모던: 회피const그리고.volatile경고는 Manos Nikolaidis@ 및 @egur에 의해 해결되었습니다.가지 예선의 효과를 주목해야겠다고 생각했습니다.const,volatile,그리고.restrict.

[편집] 추가char * restrict *rp2per @R.. 코멘트

void free_test(const char *cp, volatile char *vp, char * restrict rp, 
    char * restrict *rp2) {
  free(cp);  // warning
  free(vp);  // warning
  free(rp);  // OK
  free(rp2);  // warning
}

int main(void) {
  free_test(0,0,0,0);
  return 0;
}

다음은 깁스를 하지 않으면 무료가 실패할 수 있는 예입니다.

volatile int* p = (volatile int*)malloc(5 * sizeof(int));
free(p);        // fail: warning C4090: 'function' : different 'volatile' qualifiers
free((int*)p);  // success :)
free((void*)p); // success :)

C에서는 경고를 받을 수 있습니다(VS2012에서는 경고를 받았습니다).C++에서는 에러가 발생합니다.

드문 케이스는 차치하고, 캐스팅은 코드를 부풀릴 뿐이고...

편집: 캐스팅 대상void*것은 아니다.int*에러를 데모합니다. 하면 됩니다.int* will will will will will will 로 변환됩니다.void*★★★★★★★가 추가되었습니다.int*

free는 상수 이외의 포인터만 파라미터로 가져옵니다.따라서 const 포인터의 경우 non-const 포인터에 대한 명시적 캐스팅이 필요합니다.

C에서 const 포인터를 해방할 수 없습니다.

언급URL : https://stackoverflow.com/questions/34019977/in-c-why-do-some-people-cast-the-pointer-before-freeing-it

반응형