IT story

memset보다 bzero를 사용하는 이유는 무엇입니까?

hot-time 2020. 6. 13. 09:45
반응형

memset보다 bzero를 사용하는 이유는 무엇입니까?


시스템 프로그래밍 클래스에서이 전 학기를 수강했습니다. C에서 기본 클라이언트 / 서버를 구현해야했습니다. sock_addr_in, 또는 버퍼 버퍼 (클라이언트와 서버간에 데이터를주고받는 데 사용 된) 와 같은 구조체를 초기화 할 때 교수 초기화 만하지 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하는 내장 구현을 사용 합니다. 내장이 비활성화 된 경우 와 동일합니다 .memset0glibc


W. Richard Stevens의 UNIX 네트워크 프로그래밍 을 사용했거나 교사의 영향을 받았다고 생각합니다 . 그는 최신 버전에서도 bzero자주 사용하지 memset않습니다. 이 책은 매우 인기가 많기 때문에 네트워크 프로그래밍의 관용구가 된 것 같습니다.

더 이상 사용되지 않으며 이식성이 줄어들 memset기 때문에 간단하게 고수 할 것 bzero입니다. 나는 당신이 다른 하나를 사용함으로써 실질적인 이익을 볼 수 있을지 의심합니다.


내가 생각하는 장점 중 하나 bzero()이상이 memset()제로에 메모리를 설정 만들어지고 실수의 감소 가능성이 있다는 것이다.

한 번 이상 다음과 같은 버그가 발생했습니다.

memset(someobject, size_of_object, 0);    // clear object

컴파일러는 (컴파일러에 경고 수준을 크 랭킹 할 수도 있지만) 메모리가 지워지지 않을 것입니다. 이것은 객체를 휴지통에 버리지 않기 때문에 그냥 내버려두기 때문에 버그가 분명하게 나타나지 않을 가능성이 있습니다.

bzero()표준이 아니라는 사실 은 사소한 자극입니다. (FWIW, 프로그램에서 대부분의 함수 호출이 표준이 아닌 경우 놀라지 않을 것입니다. 사실 그러한 함수를 작성하는 것이 일종의 일입니다.)

또 다른 답변에 대한 언급에서 Aaron Newton은 Stevens, et al., Section 1.2 (강조 추가)의 Unix Network Programming, Volume 1, 3rd Edition에서 다음을 인용했습니다.

bzeroANSI C 함수가 아닙니다. 초기 Berkely 네트워킹 코드에서 파생되었습니다. 그럼에도 불구하고, 우리는 대신 ANSI C의의 텍스트 전체에 사용 memset하기 때문에, 기능 bzero이상 (두 개의 인수)을 기억하는 것이 더 쉽습니다 memset(세 개의 인수). 소켓 API를 지원하는 거의 모든 벤더는 또한을 제공 bzero하며, 그렇지 않은 경우 unp.h헤더에 매크로 정의를 제공합니다 .

실제로, TCPv3의 저자 [TCP / IP Illustrated, Volume 3-Stevens 1996]는 memset첫 번째 인쇄에서 두 번째와 세 번째 인수를 10 번 으로 바꾸는 실수를 했습니다 . 두 인수가 모두 같은 유형이므로 AC 컴파일러는이 오류를 포착 할 수 없습니다. 실제로 두 번째 인수는 일반 int적이고 세 번째 인수는 size_t일반적으로 unsigned int이지만 다른 유형의 인수에는 각각 0과 16으로 지정된 값을 memset여전히 사용할 수 있습니다. 소켓 함수 중 일부는 실제로 인터넷 소켓 주소 구조의 마지막 8 바이트를 0으로 설정해야합니다. 그럼에도 불구하고, 오류 bzero는 두 인수를 다음과 같이 바꿔서 사용하여 피할 수있는 오류였습니다.bzero 함수 프로토 타입을 사용하는 경우 항상 C 컴파일러에서 잡습니다.

또한 대부분의 호출 memset()은 메모리를 0으로하는 것이므로 해당 사용 사례에 맞는 API를 사용하지 않는 이유는 무엇입니까?

가능한 단점 bzero()은 컴파일러가 memcpy()표준이기 때문에 컴파일러가 최적화 될 가능성이 높기 때문에이를 인식하도록 작성 될 수 있다는 것입니다. 그러나 올바른 코드는 여전히 최적화 된 잘못된 코드보다 낫습니다. 대부분 bzero()bzero()경우을 사용 하면 프로그램 성능에 눈에 띄는 영향을 미치지 않으며으로 확장되는 매크로 또는 인라인 함수일 수 있습니다 memcpy().


한마디로 : memset 더 많은 어셈블리 작업이 필요합니다 bzero.

이것은 소스입니다 : http://fdiv.net/2009/01/14/memset-vs-bzero-ultimate-showdown


bzero 대 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 일이었다.

그리고 단어 "했다"참고 - 그것이 되지 POSIX.1-2001과 제거 당신은 더 나은 표준 C 함수를 사용하여 길 이죠, 그래서 memset 함수에 복종에 POSIX.1-2008에.


원하는 방식으로 사용하십시오. :-)

#ifndef bzero
#define bzero(d,n) memset((d),0,(n))
#endif

참고 :

  1. 원본 bzero은 아무것도 반환하지 않고 memsetvoid 포인터 ( d)를 반환합니다 . 이것은 정의에서 void에 typecast를 추가하여 해결할 수 있습니다.
  2. #ifndef bzero원래 기능이 존재하더라도 숨길 수는 없습니다. 매크로가 있는지 테스트합니다. 이것은 많은 혼란을 야기 할 수 있습니다.
  3. 매크로에 대한 함수 포인터를 만드는 것은 불가능합니다. bzerovia 함수 포인터를 사용하면 작동하지 않습니다.

memset 함수 함수, 제 2 인수가 인 int세 번째 인자 인 size_t,

void *memset(void *s, int c, size_t n);

which is typically an unsigned int, but if the values like, 0 and 16 for second and third argument respectively are entered in wrong order as 16 and 0 then, such a call to memset can still work, but will do nothing. Because the number of bytes to initialize are specified as 0.

void bzero(void *s, size_t n)

Such an error can be avoided by using bzero, because swapping the two arguments to bzero will always be caught by the C compiler if function prototypes are used.


memset takes 3 parameters, bzero takes 2 in memory constrained that extra parameter would take 4 more bytes and most of the time itll be used to set everything to 0

참고URL : https://stackoverflow.com/questions/17096990/why-use-bzero-over-memset

반응형