2010-02-17 5 views
6

나는 메모리 블록 복사 루틴을 만들고 있으며 효율적인 청크에서 원시 메모리 블록을 처리해야합니다. 내 질문은 * 내가 만들고있어 전문 복사 루틴에 대한 것이 아니라 방법에 올바르게의가 이미 null 이외의 문자로 던져 말할 수 있도록, 내가 메모리의 원시 포인터를 원시 포인터 조작을위한 승인 된 구문

C.

에 원시 포인터 정렬을 검사 . 제 아키텍처에서는 64 바이트 청크로 메모리를 효율적으로 복사 할 수 있습니다. 따라서 (표준) 트릭은 헤드 및/또는 꼬리에서 0-63 바이트의 간단한 복사본을 만들어 임의의 길이의 임의의 char *에서 64 바이트의 정렬 된 포인터로 복사를 변환하는 것입니다. 길이가 64 바이트입니다.

이제는 어떻게 합법적으로 포인터를 검사하여 정렬을 결정 (및 조작)합니까? 확실한 방법은 정수로 캐스팅 그냥 비트 검토하는 것입니다 : 여기

char *pointer=something. 
int p=(int)pointer; 
char *alignedPointer=(char *)((p+63)&~63); 

주 내가 alignedPointer 포인터와 같은 메모리를 가리 키지 않는다는 것을 깨닫게을 ...이 (가) "반올림"입니다 포인터를 복사하여 효율적인 복사 루틴을 호출 할 수 있으며 처음에는 수동으로 다른 바이트를 처리 할 것입니다.

그러나 컴파일러는 (정당하게) 정수로 포인터를 캐스팅 할 때 놀라지 않을 것입니다. 하지만 그 밖에 어떻게 포인터의 하위 비트를 검사하고 조작 할 수 있습니까? LEGAL C? 이상적으로 다른 컴파일러를 사용하면 오류나 경고가 발생하지 않습니다. 포인터를 저장하기에 충분히 큰 정수 유형의

+0

'int'가 포인터 유형과 동일한 크기 인 한 확인해야합니다. –

+0

http://stackoverflow.com/questions/1898153/how-to-determine-if-memory-is-aligned-testing-for-alignment-not-aligning/1898194 –

+0

아, 포인터는 MSB에서 LSB로 바이너리로 저장된다는 것을 전제로합니다. 우리는 무엇을 가지고 있나? * 정의되지 않은 행동! * (치명적인 무기 녀석이 외교적 면책 특권을 말하는 것과 같은 방식으로! *) 실제 세계에서 효과가 있기 때문에 그것이 덜 정의되지는 않습니다. ;-) –

답변

7

는 C99 stdint.h가있다 : 데이터의 경우

은 길이있다 :

  • size_t
  • C99 전에 잘 이후 주변왔다
  • ssize_t

.

플랫폼에 이러한 코드가없는 경우에도 이러한 유형 이름을 사용하고 코드에 맞게 typedef을 적절히 사용하여 코드의 이식성을 극대화 할 수 있습니다.

+0

+1 나를 때린다. –

+0

아,하지만 정렬되지 않은 포인터에서 정렬 된 * 포인터를 얻는 방법은 무엇입니까? – JustJeff

0

int 대신 포인터 (Win32/64의 경우 INT_PTR)와 같은 크기의 데이터 유형을 사용해보십시오. 어쩌면 컴파일러가 너무 괴롭히지 않을 것입니다. :) 또는 64 비트 호환성이 중요하지 않은 경우 공용체를 사용하십시오.

1

과거의 사람들은 자신의 비트 뱅킹을 꺼려했지만 어쩌면 현재의 "손대지 마라"분위기가 정렬을위한 일종의 표준 라이브러리를 만드는 누군가에게 도움이 될 것이라고 생각하지 않습니다. 포인터. 공식 api의 어떤 종류가 결여되면, 너는 AND와 OR 방법에 그러나 선택의 여지가있다.

+1

+1 과거에는 정의되지 않은 행동 * 같은 것이 없었습니다. 당신의 컴파일러가 당신이 원하는 것을했다면 충분합니다. –

0

정수와의 캐스팅 포인터는 유효하지만 결과는 구현에 따라 정의됩니다. 이 표준의 6.3.2.3 절을 보라. 의도는 결과가 시스템에 익숙한 사람이 기대하는 것 인 것으로 보이며 실제로 이것은 실제로 일상적으로 나타나는 것처럼 보입니다.

해당 아키텍처가 포인터와 정수를 효율적으로 조작 할 수 있고 문제가 해당 시스템의 모든 컴파일러에서 작동하는지 여부 만 알면 어쨌든 그 대답이 가능할 것입니다.

(필자가이 코드를 작성했다면 분명히 그렇지 않다는 것이 확실 할 것입니다.) 제 경험으로 볼 때 주어진 시스템의 컴파일러는 모두 이와 비슷한 수준에서 매우 유사한 방식으로 작동합니다. 언어는 모두 다음 걸릴 것으로, 특정 접근 방식을 제안합니다.)

이없는 아주 좋은 일반적인 조언은, 비록입니다 "아마 작품"그래서 그냥 작동하는 코드가 될 작성합니다 나의 제안, 그것은 충분히 적합 #ifdef의 서라운드 만 알려진 컴파일러가이를 컴파일하고 다른 경우에는 memcpy으로 연기합니다.

#ifdef은 거의 이상적이지 않지만 다른 가능성에 비해 상당히 가볍습니다. 구현 정의 동작이나 컴파일러 관련 트릭이 필요한 경우 옵션이 제한적입니다.

+0

"어셈블리 언어는 특정 접근 방식을 제안합니다."- 적용 가능성에 관계없이 소프트웨어 토론에서이 구를 사용하기 시작할 것입니다. – notJim

관련 문제