2016-10-30 3 views
0

그래서 배열 A의 요소에 대한 포인터를 반환하는 함수가 있습니다. 포인터를 매개 변수로 사용하는 또 다른 함수가 있습니다. 그러나, 나는 완전히 임의의 포인터를 전달할 수있는 가능성을 처리 할 수있는 함수가 필요합니다.포인터가 지정된 배열을 가리키고 있는지 확인하십시오.

포인터가 구조 내 어딘가를 가리키는 지 감지 할 수있는 방법이 있습니까? 이 경우, 내 배열 A?

나는 C에 대한 비슷한 질문 ++ 본 적이 있지만 C.와

섹션에서
+0

아마도 다른 질문이 있습니다. 정렬. 표준은 작동 할 것이라고 말하지 않지만 배열 시작, 요소 수 및 각 요소의 크기뿐만 아니라 주어진 포인터를 알면 주어진 포인터가 배열의 시작과 끝.문제는 포인터가 범위를 벗어난 경우 비교가 표준에 의해 작동하지 않을 것이라는 점입니다. 요즘 대부분의 경우 세그먼트 화되지 않은 컴퓨터 (대부분)에서 실제로 작동합니다. –

+0

배열을 다루는 경우 왜 오프셋을받지 못합니까? 즉, 색인으로 사용되는 간단한 정수입니다. 그렇게하면 소속 검사를 줄일 수 있습니다. –

답변

3

유일하게 이식 가능한 방법은 포인터에 대해 가능한 모든 유효한 값에 대해 동등성 테스트를 사용하는 것입니다. 두 포인터가 실제로 (단부 과거 또는 1)와 동일한 어레이의 소자에 점을 수행하지 않는 두 포인터 관계 연산자 (예 <) 또는 뺄셈을 이용하여 정의되지 않은 동작인지

int A[10]; 

bool points_to_A(int *ptr) 
{ 
    for (int i = 0; i < 10; ++i) 
     if (ptr == &A[i]) 
      return true; 

    return false; 
} 

참고 : 예를 들어 .

+0

영리한! 그것은 경고를 제거합니다 – Bob

+0

'int 배열 [100000];'... 아! 그러나 그것이 표준이 작동 할 것이라고 말하는 것입니다. –

+0

포인터를 빼는 것 (예를 들어,'ptr -A')이 두 포인터가 같은 배열에서 나오거나 C++에서 나오지 않는 한 정의되지 않은 동작을 산출한다고 말할 만합니다. –

1

은 §6.5.8 관계 연산자는 C11 표준 (ISO/IEC 9899 : 2011) 말한다 :

두 포인터를 비교할 때 결과는 가리키는 대상의 주소 공간에있는 상대 위치에 따라 다릅니다. 객체 유형에 대한 두 개의 포인터가 모두 같은 객체를 가리 키거나 둘 다 동일한 배열 객체의 마지막 요소를 가리키는 경우이 두 객체는 ​​동일한 것을 비교합니다. 가리키는 개체가 동일한 집계 개체의 멤버 인 경우 나중에 선언 된 구조체 멤버에 대한 포인터는 구조체에서 이전에 선언 된 멤버보다 큰 포인터를 비교하고 큰 첨자 값을 가진 배열 요소에 대한 포인터는 동일한 배열의 요소에 대한 포인터보다 큽니다 첨자 값이 낮습니다. 같은 공용체 객체의 멤버에 대한 모든 포인터는 동등한 값을 비교합니다. 표현식 P이 배열 객체의 요소를 가리키고 표현식 Q이 동일한 배열 객체의 마지막 요소를 가리키는 경우 포인터 표현식 Q+1P보다 큽니다. 다른 모든 경우에는 동작이 정의되지 않습니다.

포인터가 배열의 범위 내에 있다는 것을 알고 있으면 비교가 작동합니다. 포인터가 범위를 벗어나면 비교가 작동하는지 확신 할 수 없습니다. 실제로, 보통 그렇지만 표준은 명시 적으로 비교가 정의되지 않은 동작을 산출한다고 말합니다. 배열 SomeType array[20];위한 어드레스 &array[20]가 유효하고 &array[19] 통해 &array[0]에서 모든 어드레스와 비교 신뢰성을 보장

참고. 배열에있는 것으로 계산할지 여부를 결정해야합니다.

int within_int_array(int *array, size_t num_ints, int *ptr) 
{ 
    return ptr >= array && ptr < array + num_ints; 
} 

요즘, 당신은 정의되지 않은 동작을 호출에 대해 더욱주의해야합니다 : 표준이 작동을 보장하지 않습니다 관찰에

주제는 다음 두 가지 int 포인터를 비교할 수 있습니다. 컴파일러는 정의되지 않은 동작을 사용하는 프로그램에 불쾌한 일을합니다. 기술적으로 "표준이 정의되지 않은 동작"이라고 말하기 때문에 당신은 아무런 의지가 없습니다.

+0

커다란 [~ 100000] 배열에 대한 이전 코멘트에 대해 : 배열에 대해 자주 테스트해야한다면 배열에 대한 모든 유효한 포인터를'uintptr_t'로 캐스팅하고 해시 테이블을 만들 수는 없습니다. 포인터'p'가 배열의 요소를 가리키는 지 알아 내기 위해'p'를'uintptr_t'로 캐스팅하고, 결과를 해시하고 테이블을 검사 할 수 있습니다. 아니면 그냥 나쁜 생각입니까? –

+1

@DavidBowling : 해시 테이블 같은 것이 사용될 수는 있지만 너무 많은 인프라를 필요로하는 것보다 포인터가 가리키는 곳을 아는 것이 더 좋을 것이라고 생각합니다. –

관련 문제