구체적으로, 말록의 결과를 캐스팅하는 것이 위험한 것은 무엇입니까?
사람들이 이걸 가짜라고 표시하기 전에 다음 글을 다 읽었는데, 그 중 어느 것도 내가 원하는 답을 제공하지 않는다.
- C FAQ: malloc의 수익률 캐스팅에 문제가 있는 것은 무엇입니까?
- SO: malloc()의 반환값을 명시적으로 캐스팅해야 합니까?
- 불필요한 포인터 캐스트(C)
- malloc의 결과를 섭외해야 하나요?
은 모두 C FAQ를 캐스팅하는 하고 있습니다.malloc의 반환값은 숨길 수 있지만 실제로는 이러한 오류를 나타내는 구체적인 예는 없습니다.내가 경고한 것이 아니라 오류라고 말한 것에 주목해라.
다음 코드가 지정되었습니다.
#include <string.h>
#include <stdio.h>
// #include <stdlib.h>
int main(int argc, char** argv) {
char * p = /*(char*)*/malloc(10);
strcpy(p, "hello");
printf("%s\n", p);
return 0;
}
위의 코드를 gcc 4.2로 컴파일하면 캐스트 유무에 관계없이 동일한 경고가 발생하며 프로그램이 올바르게 실행되어 두 경우 모두 동일한 결과를 얻을 수 있습니다.
anon@anon:~/$ gcc -Wextra nostdlib_malloc.c -o nostdlib_malloc
nostdlib_malloc.c: In function ‘main’:
nostdlib_malloc.c:7: warning: incompatible implicit declaration of built-in function ‘malloc’
anon@anon:~/$ ./nostdlib_malloc
hello
캐스팅으로 인해 할 수 오류 또는 를 들 수?malloc니면면 그냥?
편집 이 문제와 관련하여 두 가지 잘 작성된 주장을 접했습니다.
- 캐스팅에 찬성: CERT 권고:메모리 할당 함수 호출 결과를 할당된 유형에 대한 포인터에 즉시 캐스트합니다.
- 캐스팅 반대(2012-02-14 기준 404 오류: 2010-01-27 인터넷 아카이브 웨이백 머신 사용).{2016-03-18:" 페이지는 robots.txt로 인해 크롤 또는 표시할 수 없습니다."})
컴파일러 오류는 발생하지 않지만 컴파일러 경고는 표시됩니다.인용한 소스(특히 첫 번째 소스)에서 알 수 있듯이 를 포함하지 않고 캐스트를 사용하면 예기치 않은 런타임 오류가 발생할 수 있습니다.
여러분 , 출연자가 없는 것을 입니다.stdlib.h은 파음음음음음음음음음 that that that that that that that that that that that that that that that 라고 추측할 수 있습니다.malloc입니다.int, 을 하는 것입니다.void* malloc로로 합니다.int명시적 캐스팅으로 인해 포인터 유형으로 이동합니다., 「」가 됩니다.int및 포인터는 다른 바이트 수를 차지하기 때문에 유형 변환으로 인해 데이터가 손상될 수 있습니다.
다행히 최신 컴파일러는 실제 오류를 나타내는 경고를 제공합니다.「 」를 .gcc지정한 출력:암묵적인 선언이 경고됩니다.int malloc(int)는, 의 「」와이 없습니다.mallocgcc 있는 것 mallocstdlib.h.
이 오류를 방지하기 위해 출연자를 빼는 것은 대부분 글쓰기와 같은 추론이다.
if (0 == my_var)
대신
if (my_var == 0)
수 에, 「」를 할 수 있습니다.= ★★★★★★★★★★★★★★★★★」== 첫 로 이어집니다.저는 개인적으로 후자 스타일이 제 의도를 잘 반영하고 있기 때문에 후자 스타일이 더 좋고 이런 실수를 잘 안 하는 편이에요.
입니다.malloc: 하며, 하는 모든 저는 프로그래밍에서 명시적인 것을 선호하며, 일반적으로 사용하는 모든 함수의 헤더 파일을 포함하도록 이중 체크합니다.
에 대한 중 .malloc내 생각에 그것은 잘 알려진 하위 수준의 문제보다 더 중요하다(선언이 누락되었을 때 포인터를 잘라내는 것과 같다).
좋은 프로그래밍 방법은 가능한 한 유형에 의존하지 않는 코드를 쓰는 것입니다.이것은, 특히 타입명은 가능한 한 코드에 기재되어 있지 않거나, 전혀 기재되어 있지 않은 것을 의미합니다.은 캐스트캐스트는 ), 로, 타입은 인수로 합니다.sizeof)sizeof및 기타 및 일반적으로 유형 이름에 대한 기타 모든 참조.
형식 이름은 선언에 속합니다.가능한 한 유형 이름은 선언으로 제한하고 선언으로만 제한해야 합니다.
이 관점에서 보면 이 코드 부분은 좋지 않다.
int *p;
...
p = (int*) malloc(n * sizeof(int));
그리고 이게 훨씬 낫다.
int *p;
...
p = malloc(n * sizeof *p);
'결국 '결국'의 만은 아니다.malloc의존하지 의존하지 않기 때문에 어떤 에 대해서도 자동적으로 에, 에 의존하지 않습니다.p는 사용자의 개입 없이 로 선언됩니다.
는 반환되는 으로 간주됩니다.int.
int포인터에 접속합니다.가 int이는 매우 위험한 동작입니다.
또한, 물론 일부 사람들은 경고를 오류로 간주한다. 즉, 경고가 없는 코드를 컴파일해야 한다.
는 안 된다고 합니다.void *다른 포인터 타입은 C의 기능이며, 파손될 가능성이 있는 코드를 고려합니다.
64비트 모드에서 컴파일할 때 이 작업을 수행하면 반환된 포인터가 32비트로 잘립니다.
편집: 너무 간결해서 죄송합니다.여기 설명을 위한 코드 조각의 예가 있습니다.
메인(){char * c = (char *) scaroc (2);printf % %p " , c ) ;}
반환되는 히프 포인터가 int에서 나타내는 것보다 크다고 가정합니다(예: 0xAB00000000).
malloc가 포인터를 반환하도록 프로토타입화되지 않은 경우 반환되는 int 값은 처음에는 모든 유효 비트가 설정된 일부 레지스터에 있습니다.이제 컴파일러가 "좋아요, 포인터로 변환하고 int하려면 어떻게 해야 하나요?"라고 말합니다.시제품을 생략하고 malloc에 "반환"을 지시한 하위 32비트의 부호 확장 또는 제로 확장 중 하나가 됩니다.int가 서명되어 있기 때문에 변환은 부호 확장자가 되어 이 경우 값이 0으로 변환됩니다.반환값 0xABF0000000에서는 제로 이외의 포인터가 표시되므로 참조 해제 시에도 재미를 느낄 수 있습니다.
재사용 가능한 소프트웨어 규칙:
malloc()를 사용한 인라인 함수를 쓰는 경우 C++ 코드에서도 재사용할 수 있도록 명시적인 타입 캐스팅(예를 들어 (char*))을 실시해 주세요.그렇지 않으면 컴파일러가 불만을 제기합니다.
C의 보이드 포인터는 명시적 캐스트 없이 임의의 포인터에 할당할 수 있습니다.컴파일러는 경고를 보내지만 타입 캐스팅에 의해 C++에서 재사용할 수 있습니다.malloc()대응하는 타입에 대응합니다.아웃 타입 주조에서는 C가 엄격한 타입 체크가 아니기 때문에 C에서도 사용할 수 있습니다.하지만 C++는 엄격하게 활자 검사이기 때문에 캐스팅을 입력해야 합니다.malloc()C++라고 하다.
언급URL : https://stackoverflow.com/questions/1565496/specifically-whats-dangerous-about-casting-the-result-of-malloc
'source' 카테고리의 다른 글
| 소켓 프로그래밍의 htons() 함수 (0) | 2022.08.17 |
|---|---|
| 'vue-test-utils' 및 'jest'를 사용한 'Created' 후크를 사용한 테스트 (0) | 2022.08.17 |
| Java에서 JSON을 사용한HTTP POST (0) | 2022.08.17 |
| Vuex 모듈에서 작업을 디스패치하려고 해도 작동하지 않습니다.[vuex] 알 수 없는 작업 유형 (0) | 2022.08.17 |
| Java String에는 몇 글자를 사용할 수 있습니까? (0) | 2022.08.17 |