이 질문은 실제로 Python/C API (PyObject_NewVar
, PyObject_VAR_HEAD
, PyTypeObject.tp_basicsize
and .tp_itemsize
에 가변 길이 유형을 사용하는 방법에 관한 것이지만이 질문은 귀찮게하지 않고도 물어볼 수 있습니다. API의 세부 사항을 알고 싶습니다. struct
안에 배열을 사용해야한다고 가정하십시오.동적으로 할당 된 구조체 (배열 구조체)에 동적 배열 할당
두 가지 방법 중 하나로 목록 데이터 구조를 만들 수 있습니다 (지금은 char
목록 만 보겠다. 중요하지 않습니다.) 첫 번째 포인터는 두 개의 할당이 필요합니다. #include
무시하고 오류 처리 :
struct listptr {
size_t elems;
char *data;
};
struct listptr *listptr_new(size_t elems) {
size_t basicsize = sizeof(struct listptr), itemsize = sizeof(char);
struct listptr *lp;
lp = malloc(basicsize);
lp->elems = elems;
lp->data = malloc(elems * itemsize);
return lp;
}
목록을 만드는 두 번째 방법은 배열 표기법과 하나의 할당을 사용합니다. (나는 꽤 그것을 철저하게 테스트했기 때문에이 두 번째 구현이 작동 알고있다.) 두 경우 모두
struct listarray {
size_t elems;
char data[1];
};
struct listarray *listarray_new(size_t elems) {
size_t basicsize = offsetof(struct listarray, data), itemsize = sizeof(char);
struct listarray *la;
la = malloc(basicsize + elems * itemsize);
la->elems = elems;
return lp;
}
, 당신이 다음 배열에 액세스 할 수 lp->data[index]
를 사용합니다.
제 질문은 왜 두 번째 방법이 효과가 있습니까? char data[]
, char data[0]
, char *data
또는 char data
대신 char data[1]
을 신고하는 이유는 무엇입니까? 특히, 의 작업 방식에 대한 직관적 인 이해는 data
을 선언하는 올바른 방법은 포인터 또는 배열 표기법이 전혀없는 char data
이라는 것입니다. 마지막으로, 은 basicsize
과 itemsize
의 두 계산에서 모두 올바른 계산입니다? 특히, 모든 컴퓨터에서 올바른 offsetof
사용이 보장됩니까?
업데이트
분명히이 호출되는 struct hack : C99에서, 당신은 flexible array member 사용할 수 있습니다 이해와
struct listarray2 {
size_t elems;
char data[];
}
을 당신 런타임에 data
에 대한 malloc
충분한 공간이 있습니다. C99 이전에는 선언이 일반적이었습니다. 그래서 지금 내 질문은 char data[1]
또는 대신 char *data
또는 char data
을 선언하는 이유는 무엇입니까?
'char data [1]'과'char data []'는 구조체와 연속 된 배열을 유지한다는 것을 알고 있습니다. 내 질문에 묻는 질문은 왜'char data'가 두 번째 코드 예제와 같은 방식으로 작동하지 않는가하는 것입니다. – wkschwartz
@wkschwartz 기술적으로는 효과가 있지만 왜 내 생각에 대한 내 대답이 업데이트되는지 확인하십시오. – mshildt