, 그것은 중요 그 라이브러리 기록한 '계약'이 자사의 서비스를 사용하는 응용 프로그램에 있습니다. 라이브러리 작성자는 라이브러리가 만든 모든 할당과 응용 프로그램에서 해제해야하는 것을 문서화합니다. 다른 계약과 마찬가지로 간단하고 일관성이있는 것이 좋습니다. 이 특별한 경우
, 나는 도서관도 제공해야한다고 가정 구조를 자유롭게
void free_bs(bs *b)
{
if (b->d) {
/* free b->d here */
}
/* free rest of the structure */
}
합니다. 여기서 d 배열을 해제하는 것도 의미가 있습니다. 응용 프로그램에는 모든 bs
구조에 대한 포인터가 있으며 더 이상 필요하지 않을 때 free_bs
을 호출 할 책임이 있습니다.
예를 들어 향후 사용을 위해 d를 유지하려면 라이브러리 작업을 완료 한 후에 계약서가 좀 더 복잡합니다. 이 라이브러리는 또한 제공 할 수있다 : d
에 대한 포인터를 반환하고 무료 루틴을 건너 뛸 알 수 있도록 필드를 비워 둡니다
double** bs_get_data(bs *b)
{
double **d = b->d;
b->d = NULL;
return b->d;
}
합니다.
bs_get_data()
의 문서는 한 번만 호출 할 수 있으며 응용 프로그램에서는이 경우 배열을 해제 할 책임이 있음을 설명해야합니다.
UPDATE : 아래의 코멘트에 대한 답변에서 : 우선은, 다음 (적어도) 나는 가정하여 문제를 단순화 것을 참고 : d
이 하나의 bs
구조 또는 응용 프로그램 중 하나를 참조 . 응용 프로그램과 라이브러리는 배열에 대한 하나의 참조를 서로 "전달"합니다.동일한 d
배열을 bs
구조체에 넣고 싶다면 내 접근 방식으로는 충분하지 않습니다.
의견에 제안한 플래그는 도움이 될 수 있지만 표준 방식 인 FWIK는 아닙니다. 이 경우, 간단하게 참조 계산을 구현하는 것이 좋습니다. new_bs()
에서 1.
typedef struct {
double **d;
int ref;
} d_t;
초기화 ref
및 d
의 "복사"를받는 모든 기능에, 참조 카운트를 증가 : d
주위를 공유 할 필요가있는 자원 인 경우에게 "개체"를 만들 . bs
구조가 삭제되거나 응용 프로그램에 d
이 더 이상 필요하지 않은 경우 참조 횟수를 감소시킵니다. 0이되면 해제하십시오. 어떤면에서는 고급 언어가 당신을 위해하는 일이며 자원 관리를 제재로 유지하는 데 매우 효율적입니다.
아무도 그 어레이를 소유하고 있지 않지만, 누구도 그 어레이를 소유하고 있지 않습니다.
물론 작업이 많이 필요하고 코드가 복잡하므로 균형을 맞추어보세요. 소유하고있는 모든 구조에는 필요하지 않지만 여러 참조를 유지해야하는 경우에만 필요합니다.
출처
2009-08-05 23:03:52
tsg
매우 빠른 답변을 보내 주셔서 감사합니다. ** d의 소유권을 표시하는 "storageMode"(내부/외부) 필드를 포함시키는 것이 합리적입니까? free_bs는 내부적으로 소유 된 경우에만 해제됩니다 (b -> d). 이렇게하면 호출자가 ** d를 해제해야 할 책임이 있다는 점에서 계약이 명시 적으로 적용됩니까? 구조체 내에 공유 객체를 사용하는 데 다른 문제가 있습니까? OO 사람들이 그런 연습을 싫어하는 것 같습니다! 거기에 합리적인 대안, 데이터 복사를 포함하지 ?? 감사합니다. tr – user151410
응답에서 내 대답을 편집 했으므로 더 쓸 수 있습니다 :-). 즉, 참조 카운팅을 고려할 수 있습니다. – tsg