2011-01-03 5 views
3

포인터를 세트 x의 일부 또는 세트 y의 일부로 태그 지정하는 방법이 필요합니다 (즉, 태그에 2 개의 '상태'만 있음). 즉, 태그없는 것으로 가정 할 수 있음 = x와 tagged = y. 태그 지정/인코딩 포인터

은 현재 내가이 일을 비트 XOR을 사용하여 찾고 있어요 :

ptr^magic = encoded_ptr 
encoded_ptr^magic = ptr 

하지만 포인터가 처음에 태그가 있는지 확인하는 방법에 난처한 해요. 링크 된 목록에서 어떤 풀 노드가 왔는지 표시하려면 이것을 사용하고 있습니다. 따라서 해당 식별자가 탈락되면 올바른 쪽으로 되돌아 갈 수 있습니다.

업데이트

그냥 내가 sizeof(void*)에 제한있어 여분의 데이터 멤버에 플래그를 저장하기 위해 제안 모든 사람들에게 그것을 명확하게하기 위해, 그래서 새 멤버를 추가 할 수 없습니다, 다른 나는 것 . 또한 풀은 연속적이지 않으며 많은 페이지로 구성됩니다. 범위를 추적하면 너무 많은 오버 헤드가 추가됩니다 (번 & 간단한 해결책 인 경우이를 호출 할 수 있음).

+0

포인터와 함께 저장된 외부 'bool' 플래그를 사용하지 않는 이유는 무엇입니까? –

답변

14

대부분의 솔루션은 플랫폼에 따라 다릅니다. 여기 몇 가지 :

1) malloc 또는 new에 의해 반환 된 포인터는 정렬됩니다 (4, 8, 16, 32 바이트, 사용자 이름). 따라서 대부분의 아키텍처에서 주소의 몇 LSB 비트는 항상 0이됩니다.

2) Win32 특정 방식 : 프로그램에서 3GB 스위치를 사용하지 않는 경우 모든 usermode 포인터의 값이 0x80000000보다 작으므로 가장 높은 비트 플래그로 사용할 수 있습니다. 보너스로 플래그가 지정된 포인터가 복구되지 않고 참조 해제 된 경우에도 충돌이 발생합니다.

+3

모든 포인터가 최소한 4에 정렬되도록 보장 할 수 있으므로 정렬에 대해 완전히 잊어 버렸으므로 완전히 내 문제를 해결할 수 있습니다. :) – Necrolis

0

성능이 큰 문제가 아닌 경우 두 개의 std :: set을 사용할 수 있습니다.

이 정보를 빨리 얻는 것이 중요하고 2 바이트 정렬 포인터 만 사용하는 것이면이 정보를 저장하는 데 가장 낮은 비트를 사용할 수 있습니다. 하지만 "해킹 된"포인터를 사용하면 오류가 발생하기 쉬운 것처럼 보일 수 있습니다. ...

8

그런 종류의 작업을 수행하는 안전하고 이식 가능한 방법은 없습니다. 항상 알려진 값 (예 : 가장 중요한 n 비트) 인 시스템 특정 비트를 찾을 수는 있지만 이는 매우 취약하고 위험한 것입니다. 포인터의 일부 비트가 처음에 알려진 값을 가지고 있지 않으면 포인터가 "표시"되어 있는지 여부를 알 수 없습니다.

이렇게하는 것이 훨씬 더 좋은 방법은 포인터가 가리키는 구조에 식별자를 저장하는 것입니다.

0

ptr1^magic = ptr2는 세트 X에 ptr1을, 세트 Y에 ptr2를 가질 수 있습니다 (그렇지 않으면 증명하지 않는 한). (필자는) 포인터 주소를 제어 할 수 없기 때문에 기술이 적절하지 않은 것 같습니다.

Vinay 솔루션의 대안은 미리 할당 된 버퍼의 비트로 태그를 저장하는 것입니다 (버퍼 크기를 늘리거나 줄이지 않아도 목록의 크기가 제한되는 경우 특히 쉽습니다). 이는 뾰족한 데이터 구조를 수정할 필요가없는 매우 컴팩트하고 효율적인 솔루션입니다.

건배, 각 메모리를 할당 할 때 만, 2 개 개의 수영장이있는 경우

2

확실히 -stan

는 가능한 주소 범위를 알고 풀 - 왜 당신의 주어진 포인터가 하나 발생 여부를 확인하지 간단한 포인터 연산과 다른 주소 범위?