memset에 bzero를 사용하는 이유는 무엇입니까?
이번 학기에 들었던 시스템 프로그래밍 수업에서는 C에 기본 클라이언트/서버를 구현해야 했습니다.구조물을 초기화할 때, 예를 들어sock_addr_in
또는 char buffers(클라이언트와 서버 간에 데이터를 주고받을 때 사용)는 교수님이 사용만 하라고 지시하셨습니다.bzero
가 아니라memset
초기화할 수 있습니다.그는 그 이유를 설명하지 않았고, 나는 이것에 대한 타당한 이유가 있는지 궁금합니다.
여기 http://fdiv.net/2009/01/14/memset-vs-bzero-ultimate-showdown에서 확인하실 수 있습니다.bzero
메모리가 제로화되기 때문에 더 효율적입니다.따라서 추가 체크가 필요 없습니다.memset
그럴 수도 있어요.아직까지는 이 제품을 전혀 사용하지 않을 이유가 없는 것 같습니다.memset
메모리 제로화를 위해서요.
bzero
는 권장되지 않는 것으로 간주되며 표준 C 함수가 아닙니다.매뉴얼에 따르면memset
보다 바람직하다bzero
이 때문에그럼 왜 아직도 이 제품을 사용하고 싶은 거죠?bzero
에 걸쳐서memset
효율 향상을 위해서일까요, 아니면 그 이상의 것을 위해서일까요?마찬가지로, 의 이점은 무엇입니까?memset
에 걸쳐서bzero
새로운 프로그램에서는 사실상 선호되는 옵션입니다.
내가 더 좋아할 이유는 없다bzero
에 걸쳐서memset
.
memset
는 표준 C 함수입니다.bzero
C 표준 함수가 된 적이 없습니다.그 이유는 아마도 다음과 같은 기능을 사용할 수 있기 때문일 것입니다.memset
기능.
효율성에 관해서는 컴파일러는gcc
빌트인 실장을 사용하다memset
특정 구현으로 전환되는 상수는0
검출되었습니다.동일glibc
디세블로 되어 있는 경우.
내가 생각하는 유일한 장점은bzero()
끝나다memset()
메모리를 0으로 설정하면 실수할 확률이 낮아집니다.
다음과 같은 버그를 여러 번 접했습니다.
memset(someobject, size_of_object, 0); // clear object
컴파일러는 불평하지 않고(일부 컴파일러의 경고 레벨을 올리는 것은 가능하지만), 그 결과 메모리가 클리어 되지 않습니다.왜냐하면 이것은 물체를 버리는 것이 아니라 그냥 내버려 두기 때문이다. 이 벌레가 명백한 어떤 것으로도 나타나지 않을 가능성이 충분히 있다.
이 사실은bzero()
표준이 사소한 자극이 아닙니다.(FWIW, 프로그램의 대부분의 기능 호출이 표준이 아니더라도 놀라지 않을 것입니다.사실 그런 기능을 쓰는 것은 제 일의 일종입니다.)
Aaron Newton은 여기서 또 다른 답변에 대한 코멘트에서 Unix Network Programming, Volume 1, Stevens의 3rd Edition, Section 1.2(강조 추가)에서 다음을 인용했습니다.
bzero
는 ANSI C 함수가 아닙니다.초기 버클리 네트워크 코드에서 파생되었습니다.단, ANSI C 대신 텍스트 전체에서 사용합니다.memset
기능, 이유는bzero
(2개의 인수만으로) 기억하기 쉽다.memset
(3개의 인수를 사용).소켓 API를 지원하는 거의 모든 벤더는bzero
않은 에는 ''를 '마크로 정의'에unp.h
머리글실제로 TCPv3 [TCP/IP Illustrated, Volume 3 - Stevens 1996]의 저자는 첫 번째 인쇄에서 두 번째 및 세 번째 인수를 10회 만에 스왑하는 실수를 범했습니다.두 인수가 같은 유형이기 때문에 C 컴파일러는 이 오류를 검출할 수 없습니다.(실제로 두 번째 인수는
int
는 '''입니다.size_t
으로 '''는 ''')입니다.unsigned int
은 다른 할 수 의 콜memset
하고 있습니다.0으로 가 있는 은 소켓 입니다.실제로 인터넷소켓 주소 구조의 마지막 8바이트를 0으로 설정할 필요가 있는 것은 소켓 기능의 일부뿐이기 때문입니다.였고, 은 '오류 '오류', '오류', '오류'를하면 피할 수 오류였다.bzero
두 의 인수가 2개의 인수로 때문입니다.bzero
함수 프로토타입을 사용하면 C 컴파일러에 항상 잡힙니다.
, 「 」에의 은, 「 」라고 .memset()
메모리 제로화입니다.그러면 그 사용 사례에 맞는 API를 사용하는 것은 어떨까요?
「 」의 인 bzero()
가 최적화할 입니다.memcpy()
이게 표준이기 때문에 그걸 인식하도록 쓰여져 있을 수도 있어요.그러나 올바른 코드가 최적화된 잘못된 코드보다 더 낫다는 점에 유의하십시오.의 경우, 「」를 하고,bzero()
큰, 퍼포먼스에 큰 영향을 주지 .bzero()
는 매크로 또는 로서 「」로 할 수 .memcpy()
.
W. Richard Stevens가 UNIX Network Programming을 사용하셨다고 생각합니다.그는 사용한다.bzero
memset
이치노그 책은 인기가 많아서 네트워크 프로그래밍의 숙어가 된 것 같아서 아직도 쓰이고 있는 것 같아요.
는 계속 이랬으면 좋겠어요.memset
말해서bzero
는 폐지되어 휴대성이 저하됩니다.둘 중 하나를 다른 하나에 사용했을 때 얻을 수 있는 진정한 이점을 알 수 있을지 의문입니다.
함수의 경우 두 는 memset 입니다.int
는 '''입니다.size_t
,
void *memset(void *s, int c, size_t n);
은 통상 「」입니다.unsigned int
,, 음, 음, 음 등의 이 있는 0 and 16
두 번째 인수와 세 번째 인수에 대해 각각 16과 0의 잘못된 순서로 입력된 경우, 이러한 memset에 대한 콜은 계속 기능하지만 아무것도 하지 않습니다.가 "Byte"로 에 "Byte"는 "Byte"로 됩니다.0
.
void bzero(void *s, size_t n)
이러한 오류는 bzero를 사용함으로써 피할 수 있습니다. 왜냐하면 함수 프로토타입을 사용할 경우 두 인수를 bzero로 스왑하면 항상 C 컴파일러에 의해 포착되기 때문입니다.
마음대로 드십시오. :-)
#ifndef bzero
#define bzero(d,n) memset((d),0,(n))
#endif
주의:
- 오리지널
bzero
아무것도 반환하지 않습니다.memset
void 포인터를 반환합니다().d
) 이것은 정의에서 void에 typecast를 추가하여 수정할 수 있습니다. #ifndef bzero
원래 기능이 존재하더라도 숨길 수 있습니다.매크로의 존재를 테스트합니다.이로 인해 많은 혼란이 발생할 수 있습니다.- 매크로에 대한 함수 포인터를 만드는 것은 불가능합니다.사용시
bzero
기능 포인터를 사용하면 동작하지 않습니다.
bzero vs. memset 인수에 대해 언급하고 싶습니다.ltrace를 설치한 다음 후드 아래에서 작동하는 기능을 비교합니다.libc6(2.19-0ubuntu6.6)를 사용하는 Linux 에서는, 발신된 콜은 완전하게 같습니다.ltrace ./test123
):
long m[] = {0}; // generates a call to memset(0x7fffefa28238, '\0', 8)
int* p;
bzero(&p, 4); // generates a call to memset(0x7fffefa28230, '\0', 4)
libc의 깊은 곳이나 커널/시스콜 인터페이스를 사용하지 않는 한 걱정할 필요가 없다고 들었습니다.제가 걱정해야 할 것은 콜이 버퍼 제로잉 요건을 충족한다는 것입니다.다른 사람들이 어떤 것이 다른 것보다 더 좋은지에 대해 언급했으므로 여기서 마치겠습니다.
사용하시면 안 될 것 같습니다.bzero
사실 스탠다드 C가 아니라 POSIX 같은 거였어요.
또한 "was"라는 단어는 POSIX.1-2001에서 폐지되었으며, POSIX.1-2008에서 memset에 관해 삭제되었기 때문에 표준 C 함수를 사용하는 것이 좋습니다.
memset은 3개의 파라미터를, bzero는 4바이트를 더 필요로 하며 대부분의 경우 모든 것을 0으로 설정하는데 사용됩니다.
요컨대: memset
조립 작업이 더 필요하다bzero
.
출처: http://fdiv.net/2009/01/14/memset-vs-bzero-ultimate-showdown
언급URL : https://stackoverflow.com/questions/17096990/why-use-bzero-over-memset
'programing' 카테고리의 다른 글
사용자가 관리 vue 라우터 및 vuex인지 확인합니다. (0) | 2022.06.28 |
---|---|
gcc 옵션 -fomit-frame-pointer를 이해하려고 합니다. (0) | 2022.06.27 |
확장 루프의 null 검사 (0) | 2022.06.27 |
정확히 어떻게 이중 문자열 트릭이 작동할까요? (0) | 2022.06.27 |
문자를 Java의 ASCII 숫자 값으로 변환 (0) | 2022.06.27 |