2012-03-08 2 views
1

Cs에서 포인터 연산을 수행하는 가장 깨끗한 방법은 무엇입니까? 주소에 n 바이트를 추가하려고합니다.C++ 클린 포인터 산술

int *foo; 
foo = static_cast<int*> (static_cast<unsigned int>(foo) + sizeof(T)) 

나중에이 정도면 충분 다르게

char* somestr = reinterpret_cast<char*>(foo) 

foo는 개주 및 사용할 수 있을까? 이제 포인터 구현 dosent 모든 포인터 (char*, int*) 같은 크기로 구현 된 보장합니다. 따라서 int* (foo*이어야 함)인지 확실하지 않고 수학에 부호없는 int를 사용하는 것이 가장 깨끗한 해결책입니다. 또한 32 비트와 64 비트 모두에서 작동해야합니다.

왜 이런 짓을했는지. 그게 다 이상한 것은 아니지만. 다른 유형으로 동적으로 해석되는 데이터의 스트림 (또는 바이 패스)로 작업 할 때마다 언제든지이 문제를 해결할 수 있습니다.

+0

여기서하고있는 일은 절대적으로 잘못되었거나 잘 이해할 수 없습니다 ... 저는 RTM에 제안합니다 : http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/pointer .html –

+2

이 시대에 포인터 연산을 수행하는 합법적 인 사례는 극히 적습니다. 나는 당신이 해결하려고하는 것을 모른다. 그러나 당신은 그것을 필요로하지 않을 것이다. – David

답변

12

포인터 연산을 수행하는 가장 깨끗한 방법은 바이트 수를 사용하는 것이 아니라 강하게 입력하는 것입니다.

int* next = foo + n; 

나 :

int* next = &foo[n]; 

모두 당신의 캐스팅 솔루션 우수한 다른 뭔가로 int 배열, 다만 직접 오프셋을 취급하지 마십시오.

바이트 버퍼로 작업하는 경우 int*이 아닌 char*을 사용하십시오. 즉,

char* buffer = get_the_buffer(); 

// Pointer arithmetic uses sizeof(char) == 1 

바이트 배열이 아닌 바이트 배열에서 실제로 바이트 단위로 증가해야하는 경우 먼저 그 이유를 물어보십시오. 그런 다음 char*으로 캐스팅하고 포인터 산술 연산을 수행합니다. int 또는 다른 통합 유형에 하지 캐스트를 수행

char* foo_buffer = reinterpret_cast<char*>(foo); 
char* whatever = foo_buffer + n; 

대신 char 당신은 또한 틀림없이 바이트를 표현하는 것이 더 의미가 있지만, 포인터 연산에 영향을주지 않습니다 unsigned char를 사용할 수 있습니다. 그러나 정렬에주의하십시오. 더 이상 원래 유형을 사용하여 증가 된 포인터에 안정적으로 액세스 할 수 없습니다. 정렬되지 않은 메모리에 액세스하는 것은 정의되지 않은 동작 (= 불량!)입니다. 가장 좋은 경우에는 속도가 느립니다. 최악의 경우 충돌이 발생합니다.

이 모든 것이 극히 낮은 수준이라는 것은 자명하다. 이러한 코드에는 더 이상 사용하지 않습니다. 저수준 라이브러리조차도 이런 종류의 코드에 C++ 표준 라이브러리 기능을 사용하는 것을 선호해야하며 특히 포인터 연산은 사용이 적습니다.

+0

처음 두 단편은 질문의 내용이 아니며, foo는'int *'입니다. 확실히 버퍼 관리를 위해서'char *'를 사용하십시오. – Skizz

+0

@Skizz 솔직히 말해서 나는 무엇을 묻는 지 잘 모르겠지만'foo'라는 질문에서'int * '로 선언되고 코드가 모두 의미가 있다고 가정한다면'T'는'int'이어야합니다 따라서 코드는 효과적으로 배열 인덱싱을 수행합니다. –

+0

나는 그 점을 놓친 당신을 생각합니다. foo *는 임의의 메모리 위치 (응용 프로그램에 의해 다시 해석 됨)를 가리 킵니다. 필자는 포인터 구현이 일정하지 않아도되기 때문에 char *는 좋은 생각이라고 생각하지 않습니다. 그래서 void *가 foo를 저장하는 가장 안전한 선택인지 궁금합니다. 대답을 감사하십시오. – excalibur

1

포인터를 int로 형변환하면 실패 할 수 있습니다. 특히 int 유형의 크기가 포인터 유형의 크기와 다른 경우에는 특히 그렇습니다.

foo = reinterpret_cast <int *> (reinterpret_cast <T *> (foo) + 1); 

참고 reinterpret_cast 대신 static_cast의 사용 :

당신이 포인터 연산을 수행 할 경우

는 포인터를 사용합니다.

더 중요한 것은, 이것은 약간의 코드 냄새입니다. 여기서 무엇을하려고합니까?