구조 내 구성원의 순서가 중요합니까?
나는 C에서 특이한 행동을 발견했다.다음 코드를 고려하십시오.
struct s {
int a;
};
struct z {
int a;
struct s b[];
};
int main(void) {
return 0;
}
편찬이 잘 되네.를 바꿔주세요.z
struct z {
struct s b[];
int a;
};
오류가 .field has incomplete type 'struct s []'
왜 그런 것일까요?
의 필드 struct필드 할 수 없기 에 사이즈는 .따라서 컴파일러의 사이즈는struct패딩을 추가하면 변경될 수 있습니다.
단, 이 경우 크기를 변경할 수 있는 배열인 이른바 플렉시블 멤버를 정의합니다.유연한 멤버들의 규칙은
- 그런 멤버는 한 명밖에 없을지도 모르지만
- 경우 .
struct, 그리고. struct에는 유연한 멤버 외에 적어도1개의 멤버가 필요합니다.
유연한 구조 부재 사용에 대한 간단한 설명을 보려면 이 Q&A를 참조하십시오.
수 .struct s b[];이 컴파일러가 그 필드가어디에 있는지 알 수 뜻입니다.
에는 (를 들어) (옛 (C의) (C의) (C의) (C의)였다struct s b[];구조체의 구성원으로서 허용되지 않았습니다.이로 인해 효율적인 메모리 관리가 귀찮아졌습니다.간단한 예로, "이름" 문자열이 포함된 구조가 있다고 가정해 보십시오(단 몇 글자 또는 다수의 문자열일 수 있음).가장 큰 이름(공간 낭비)에 충분한 크기의 고정 크기 배열을 사용하거나 포인터를 사용하여 메모리 2개(구조용과 가변 길이 이름 문자열용)를 할당할 수 있습니다.또는 포인터를 사용하여 구조체의 끝을 지나 여분의 공간을 가리키도록 할 수 있습니다.그 결과 다음과 같이 됩니다.
length = strlen(my_string);
foo = malloc(sizeof(MYSTRUCTURE) + length + 1);
foo->name = (void *)foo + sizeof(MYSTRUCTURE); // Set pointer to extra bytes past end of structure
memcpy(foo->name, my_string, length + 1);
이것은 가장 효율적인 옵션이었지만, 보기 흉하고 에러가 발생하기 쉽습니다.
이 문제를 해결하기 위해 컴파일러는 구조 끝에 "알 수 없는 크기 배열"을 허용하는 비표준 확장을 추가했습니다.이것에 의해, 프로그래머가 조금 더 간단하게 할 수 있게 되어, 보다 효율적으로 할 수 있게 되었습니다(추가 포인터 멤버가 필요없기 때문에).이것은 결국 C규격에 의해 채택되었습니다(아마 C99 - 기억나지 않습니다).
멤버의 순서는 보통 중요합니다(즉, 필드 사이에 패딩을 삽입하는 경우가 있습니다).단, 유연한 멤버 어레이를 사용하는 경우, 이것은 C99 - 6.7.2.16에서 표준화되어 있습니다.
특별한 경우로서 복수의 이름 있는 멤버가 있는 구조의 마지막 요소는 불완전한 배열 타입을 가질 수 있습니다.이것은 플렉시블 배열 멤버라고 불립니다.대부분의 경우 유연한 어레이 멤버는 무시됩니다.특히 구조의 크기는 생략이 의미하는 것보다 더 많은 후행 패딩이 있을 수 있다는 점을 제외하고 플렉시블 배열 멤버를 생략한 것과 같습니다.
당신의.struct s b[];member는 여러 개의 동적 힙 할당에 액세스하기 위해 사용됩니다.struct s요소들.
질문의 제목은 "멤버 순서는 어떻게 됩니까?struct문제가 있나요?"
코드의 명백한 문제는 당신의 코드에 있는struct에는 유연한 멤버가 포함되어 있습니다.
그래서 여기 멤버들의 순서의 일반적인 질문과 관련된 추가적인 문제가 있습니다.struct:
다음 두 가지 구조를 예로 들어 보겠습니다.
struct s1
{
int a;
short b;
char c;
};
struct s2
{
char c;
short b;
int a;
};
대부분의 컴파일러는 각 멤버를 크기에 따라 나눌 수 있는 주소에 맞추기 위해 패딩을 추가합니다.
그렇게struct s2최종적으로 다음과 같이 컴파일할 수 있습니다.
struct s2
{
char c;
char pad1;
short b;
short pad2;
short pad3;
int a;
};
결과적으로 유형의 인스턴스에 따라 크기가 달라집니다.struct s1그리고.struct s2.
이 경우 순서는 중요합니다.당신의.struct z로 구성된 배열을 포함한다.structs s단, 이 어레이에는 관련된 사이즈가 없기 때문에 컴파일러는 적절한 스택스페이스를 할당하는 방법을 모릅니다.이는 구조체의 다른 필드가 있기 때문입니다.int a)을 클릭합니다.IT의 동작 예를 다음에 나타냅니다.
struct s {
int a;
}
struct z {
struct s b[10];
int a;
}
int main(void) {
return 0;
}
어레이 크기를 변경해야 할 경우 어레이를 포인터로 하여 힙에 전체 구조를 할당하는 것이 가장 좋습니다.struct s어레이 크기를 변경하기 위해 동적으로 재할당합니다.malloc (3),realloc 3),calloc (3) , , , , 입니다.free (3).
언급URL : https://stackoverflow.com/questions/26818011/does-the-order-of-members-in-a-struct-matter
'programing' 카테고리의 다른 글
| Mockito : 메서드 내에서 생성된 개체에서 메서드가 호출되었는지 확인하는 방법 (0) | 2022.08.31 |
|---|---|
| 형식 스크립트가 있는 Vue2, 유형에 속성이 없습니다. (0) | 2022.08.30 |
| C 구조체의 기본값 (0) | 2022.08.30 |
| Firebase SnapShot.val()이 vuex의 데이터에 액세스하려고 할 때 null을 반환함 (0) | 2022.08.30 |
| String #equals 메서드와 String #contentEquals 메서드의 차이 (0) | 2022.08.30 |