IT Share you

구조체 자체가 아닌 구조체의 첫 번째 요소 주소를 사용하는 이유는 무엇입니까?

shareyou 2020. 12. 6. 22:21
반응형

구조체 자체가 아닌 구조체의 첫 번째 요소 주소를 사용하는 이유는 무엇입니까?


개발자가 구조체 자체가 아닌 복사 / 비교 / 설정할 때 구조체의 첫 번째 요소 주소를 일관되게 사용하는 또 다른 코드 기반을 방금 작성했습니다. 여기에 간단한 예가 있습니다.

먼저 구조체 유형이 있습니다.

typedef struct {
    int a;
    int b;
} foo_t;

그런 다음 이러한 구조체의 복사본을 만드는 함수가 있습니다.

void bar(foo_t *inp)
{
    foo_t l;
    ...
    memcpy(&l.a, &inp->a, sizeof(foo_t));
    ...
}

나는 memcpy그런 식으로 호출을 작성 하지 않았고 원래 개발자가 단순히 C에서 포인터와 구조체를 잘 이해하지 못했다고 의심하기 시작했습니다. 그러나 이제는 관련없는 두 개의 코드베이스에서 이것을 보았습니다. 일반 개발자이므로 의심하기 시작했습니다.

왜이 스타일을 사용하고 싶습니까?


아무도 그렇게해서는 안됩니다. 구조체 멤버를 재 배열하면 문제가 발생합니다.


그 대신에:

memcpy(&l.a, &inp->a, sizeof(foo_t));

그렇게 할 수 있습니다.

memcpy(&l, inp, sizeof(foo_t));

위험하고 오해의 소지가있을 수 있지만 C가 첫 번째 구조체 멤버 앞에 패딩이 없음을 보장하므로 두 문 모두 실제로 여기서 동일한 작업을 수행합니다.

그러나 가장 좋은 방법은 간단한 할당 연산자를 사용하여 구조 객체를 복사하는 것입니다.

l = *inp;

왜이 스타일을 사용하고 싶습니까?

내 추측으로는 무지 또는 나쁜 징계.


하나는 그렇지 않습니다. a구조체에서 이동 했거나 이전 에 멤버를 삽입 한 경우 메모리 스매싱 버그가 발생합니다.


이 코드는 구조체 멤버를 재 배열 memcpy하면 멤버 a가 더 이상 첫 번째 멤버가 아닌 경우 구조체 경계를 넘어 액세스 할 수 있으므로 안전 하지 않습니다.

그러나 멤버는 의도적으로 구조체 내에서 정렬되고 프로그래머 는 멤버로 시작a 하여 구조체가 끝날 때까지 실행 되는 하위 집합 만 복사하려고 할 수 있습니다 . 이 경우 다음 변경으로 코드를 안전하게 만들 수 있습니다.

    memcpy(&l.a, &inp->a, sizeof(foo_t) - offsetof(foo_t, a));

이제 구조체 멤버는 임의의 순서로 재 배열 될 수 있으며 memcpy절대 범위를 벗어나지 않습니다.


정말 나쁜 습관입니다. 예를 들어 구조체에는 다른 멤버가 추가 될 수 있습니다. 이것은 엄청나게 부주의 한 습관이고 누구든지 이것을 할 것이라는 사실을 읽고 놀랐습니다.

다른 사람들은 이미 이것을 언급했습니다. 나를 괴롭히는 것은 다음과 같습니다.

struct Foo rgFoo [3];
struct Foo *pfoo = &rgFoo [0];

대신에

struct Foo *pfoo = rgfoo;

인덱스로 배열을 역 참조한 다음 주소를 다시 가져 오는 이유는 무엇입니까? 이미 주소입니다. 주목할만한 유일한 차이점은 pfoo가 기술적으로

struct Foo *const, 

아니

struct Foo *.  

그러나 나는 항상 첫 번째 것을 보곤했다.


실제로 이것에 대한 합법적 인 사용 사례가 하나 있습니다 : 클래스 계층 구조 구축.

구조체를 클래스 인스턴스로 취급 할 때 첫 번째 멤버 (예 : 오프셋 0)는 일반적으로 수퍼 유형 인스턴스입니다. 수퍼 유형이 존재하는 경우. 이를 통해 간단한 캐스트가 하위 유형과 상위 유형 사용 사이를 이동할 수 있습니다. 매우 유용한.

의도에 대한 Darren Stone의 메모 에서 이는 C 언어로 OO를 실행할 때 예상 됩니다.

다른 경우에는 이미 인용 된 이유로이 패턴을 피하고 대신 회원에게 직접 액세스하는 것이 좋습니다.

참고 URL : https://stackoverflow.com/questions/19776731/why-use-address-of-first-element-of-struct-rather-than-struct-itself

반응형