허당 레몬도리

https://stackoverflow.com/questions/1998752/memset-or-value-initialization-to-zero-out-a-struct

 

memset() or value initialization to zero out a struct?

In Win32 API programming it's typical to use C structs with multiple fields. Usually only a couple of them have meaningful values and all others have to be zeroed out. This can be achieved in eithe...

stackoverflow.com

https://www.py4u.net/discuss/64954

 

memset() or value initialization to zero out a struct?

Answer #1: Those two constructs a very different in their meaning. The first one uses a memset function, which is intended to set a buffer of memory to certain value. The second to initialize an object. Let me explain it with a bit of code: Lets assume you

www.py4u.net

번역 : 구글 

memset() 또는 구조체를 0으로 만들기 위한 값 초기화?
Win32 API 프로그래밍에서는 C

struct

를 여러 필드와 함께 사용하는 것이 일반적 입니다. 일반적으로 그 중 몇 개만 의미 있는 값을 가지며 나머지는 모두 제로화해야 합니다. 이는 다음 두 가지 방법 중 하나로 달성할 수 있습니다.
STRUCT theStruct;
memset( &theStruct, 0, sizeof( STRUCT ) );
또는
STRUCT theStruct = {};
두 번째 변형은 더 깔끔해 보입니다. 한 줄로 표시되며 잘못 입력되어 오류가 발생할 수 있는 매개변수가 없습니다.첫 번째 변형과 비교하여 단점이 있습니까? 어떤 변형을 사용해야 하며 그 이유는 무엇입니까?
답변 #1:
이 두 구조는 의미 매우 다릅니다. 첫 번째 는 메모리 버퍼를 특정 값 memset으로 설정 하기 위한 함수를 사용 합니다 . 두 번째로개체 초기화합니다 . 약간의 코드로 설명하겠습니다.

POD 유형

("Plain Old Data" - C++의 POD 유형이란? 참조)의 멤버 있는 구조가 있다고 가정해 보겠습니다.
struct POD_OnlyStruct
{
    int a;
    char b;
};

POD_OnlyStruct t = {};  // OK

POD_OnlyStruct t;
memset(&t, 0, sizeof t);  // OK as well

이 경우POD_OnlyStruct t = {}or 를 쓰는 것은POD_OnlyStruct t; memset(&t, 0, sizeof t)큰 차이가 없습니다. 여기서 유일한 차이점은정렬 바이트가memset사용되는 경우 0 값으로 설정된다는 것뿐입니다 . 일반적으로 해당 바이트에 액세스할 수 없으므로 차이가 없습니다.반면에 질문에 C++로 태그를 지정했으므로 POD와 다른 멤버 유형을 사용 하여 다른 예를 시도해 보겠습니다 .

struct TestStruct
{
    int a;
    std::string b;
};

TestStruct t = {};  // OK

{
    TestStruct t1;
    memset(&t1, 0, sizeof t1);  // ruins member 'b' of our struct
}  // Application crashes here

이 경우 like를 사용하는TestStruct t = {}것이 좋으며memseton을 사용하면 충돌이 발생합니다. 다음을 사용하면 어떻게 됩니까?

memset- 유형의 객체TestStruct가 생성 되어 유형의 객체 가 생성됩니다. 이는std::string구조의 구성원이기 때문입니다. 다음으로,memset객체b가 위치한 메모리 를 특정 값(예: 0)으로 설정합니다. 이제 TestStruct 개체가 범위를 벗어나면 파괴될 것이며std::string b해당 개체의 내부 구조가 모두memset

따라서 현실은이러한 것들이 매우 다르며memset어떤 경우에는 전체 구조를 0으로 만들어야 할 때도 있지만 수행 중인 작업을 이해하고 있는지 확인하고 두 번째 단계에서와 같이 실수하지 않는 것이 항상 중요합니다. 예시.내 투표 - 필요한 경우 에만memset개체에 사용하고 다른 모든 경우에는 기본 초기화 사용합니다 .

x = {}

답변자: 드미트리
답변 #2:
구조 멤버에 따라 두 변형이 반드시 동일하지는 않습니다.

memset

값 초기화는 모든 멤버를 값 0으로 초기화하는 반면 구조를 모든 비트 0으로 설정합니다. C 표준은 부동 소수점 값이나 포인터가 아닌 정수 형식에 대해서만 동일함을 보장합니다.또한 일부 API는 구조가 실제로 모두 0으로 설정되어야 합니다. 예를 들어, Berkeley 소켓 API는 구조를 다형성으로 사용하며, 명백한 값뿐만 아니라 전체 구조를 실제로 0으로 설정하는 것이 중요합니다. API 문서는 구조가 정말 모든 비트가 0이어야 하는지 여부를 말해야 하지만, 결함이 있을 수 있습니다.그러나 이들 중 어느 것도 적용되지 않거나 유사한 경우가 적용되지 않으면 귀하에게 달려 있습니다. 구조를 정의할 때 의도를 보다 명확하게 전달하는 값 초기화를 선호합니다. 물론, 기존 구조를 0화해야 하는 경우

memset

유일한 선택입니다(음, 각 멤버를 손으로 0으로 초기화하는 것을 제외하고는 일반적으로 수행되지 않지만 특히 대형 구조의 경우).
답변자: JaakkoK
답변 #3:
구조체에 다음과 같은 항목이 포함되어 있는 경우:
int a;
char b;
int c;
그런 다음 "b"와 "c" 사이에 패딩 바이트가 삽입됩니다. memset()은 그것들을 0으로 만들 것이고, 다른 방법은 그렇지 않을 것이므로 3바이트의 쓰레기가 있을 것입니다(만약 당신의 int가 32비트라면). 구조체를 사용하여 파일에서 읽기/쓰기를 하려는 경우 이것이 중요할 수 있습니다.
답변자: 밥플럭스
답변 #4:
당신이 언급했듯이 깨끗하고 오류가 덜 발생하기 때문에 값 초기화를 사용합니다. 하는 데에는 단점이 보이지 않습니다.

memset

구조체를 사용한 후에는 0으로 만드는 데 의존할 수 있습니다 .
답변 #5:
일반적이지는 않지만 두 번째 방법도 float를 0으로 초기화하는 이점이 있다고 생각합니다. memset을 수행하는 동안 확실히
답변자: 두꺼비
답변 #6:
컴파일 타임에 할 수 있기 때문에 값 초기화.

 

또한 올바르게 0이면 모든 POD 유형을 초기화합니다.memset()은 런타임에 수행됩니다.

 

또한 구조체가 POD가 아닌 경우 memset()을 사용하는 것이 의심됩니다.

 

int가 아닌 유형을 올바르게 초기화하지 않습니다(0으로).
답변자: 마틴 요크
답변 #7:
일부 컴파일러에서는 실행 파일에서 로 STRUCT theStruct = {};변환됩니다

memset( &theStruct, 0, sizeof( STRUCT ) );

. 일부 C 함수는 런타임 설정을 수행하기 위해 이미 링크되어 있으므로 컴파일러는 memset/memcpy와 같은 라이브러리 함수를 사용할 수 있습니다.
답변자: 게르하르트
답변 #8:
포인터 멤버가 많고 앞으로 더 추가할 가능성이 있는 경우 memset을 사용하는 것이 도움이 될 수 있습니다. 적절한

assert(struct->member)

호출 과 결합 하여 초기화하는 것을 잊은 잘못된 포인터를 참조하려고 시도하는 무작위 충돌을 피할 수 있습니다. 하지만 저처럼 건망증이 없으시다면 회원가입이 최고일 것입니다!

그러나

구조체가 공개 API의 일부로 사용되는 경우 memset을 요구 사항으로 사용하도록 클라이언트 코드를 가져와야 합니다. 이것은 새로운 멤버를 추가할 수 있고 클라이언트 코드가 멤버를 (위험할 수 있는) 초기화되지 않은 상태로 두지 않고 memset 호출에서 자동으로 NULL로 만들기 때문에 향후 검증에 도움이 됩니다. 이것은 예를 들어 소켓 구조로 작업할 때 수행하는 작업입니다.

 

profile

허당 레몬도리

@LemonDory

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!