2013-06-05 5 views
2

NSSet 인스턴스에서 CFSetGetValues()을 사용하려하지만 세트의 메모리가 망가져있는 것처럼 보입니다. 감시 점을 사용하면 설정된 인스턴스가 objc_assign_strongCast_non_gc()에서 기록됩니다. 지금, 나는 무슨 일이 벌어지고 있는지에 대한 단서가 없습니다. CFSetGetValues가 전달 된 NSSet을 왜곡하는 이유는 무엇입니까?

int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
    NSSet *set = [NSSet setWithObjects:@1, @2, @3, nil]; 
    const void *objects = calloc(set.count, sizeof(id)); 
    CFSetGetValues((__bridge CFSetRef)set, &objects); 
    NSLog(@"Set %@", set); // *** set has been clobbered *** 
    } 
    return 0; 
} 

은 OS X 10.8, 64 비트에있다. 동일한 코드가 iOS 시뮬레이터에서 실행될 때 실패합니다.

+0

10.8.4 버전이나 6.1 iOS 시뮬레이터에서 재생산 할 수 없습니다. – CodaFi

+0

@CodaFi는 나를 더욱 혼란스럽게 만듭니다. 로그 문은 전체 집합을 출력합니다. –

답변

3

CFSetGetValues()으로 전화 할 경우 을 &objects에서 제거해야합니다. values 매개 변수는 const void ** 유형이므로 각 요소가 임의의 포인터 (void *) 인 배열 (*)을 의미합니다. objects은 이미 배열이므로 & 연산자로 주소를 가져올 필요가 없습니다.

배열이 함수에 의해 할당 된 경우 &을 사용하는 것이 합리적이므로 주소를 호출 수신자에게 반환해야합니다. 배열을 할당 할 책임이 있기 때문에 그렇지 않습니다.

+0

또한 왜 [NSSet getObjects :]'가 (공개) API가 아닌지 잘 모르겠습니다. 'NSArray'와'NSOrderedSet'는'-getObjects : range :'를 내보내지만'- [NSSet getObjects :]'는 private입니다. –

+0

이것에 대한 또 다른 생각은'objects'는 실제로'const id *'이어야하고'id'는 이미 포인터이기 때문에'const void ** '와 비슷합니다. –

+0

'**'를 볼 때, 나는 항상'& pointer' 형태의 어떤 것으로 전달할 것을 생각합니다. 나는'id'가 포인터이기 때문에'calloc (set.count, sizeof (id)) '표현이 분명히'**'이되어'***'의 결과를 얻는 것을 보았습니다. . –