2012-09-04 2 views
4

예를 들어, Linux에서는 task_struct를 가리키는 포인터가 있습니다. 나중에 task_struct가 마이그레이션 또는 삭제 될 수 있습니다. 포인터가 여전히 task_struct를 가리키는 지 여부를 어떻게 알 수 있습니까?포인터가 특정 구조를 가리키는 지 여부를 어떻게 알 수 있습니까?

+1

"마이그레이션"을 정의하십시오. 데이터가 동적으로 할당 되었습니까? 그건 그렇고, C에서는 이런 것들을 혼자서 추적해야합니다. – ziu

답변

6

불가능합니다.

포인터에는 주소 만 포함되며 일반적으로 주어진 주소가 "유효"인지 여부를 판단 할 수 없습니다.

가끔씩 유효성이있는 엔티티를 요청한 엔티티에게 요청할 수 있지만 물론 엔티티의 정확한 세부 사항에 달려 있습니다. 언어 그 자체는 이것을 할 수 없습니다.

+0

고맙습니다.그래서 구조체가 옮겨 지거나 삭제 된 곳을 모른다면, 이전의 포인터가 프로그램을 크래쉬하지 않고 계속 유효한지 어떻게 알 수 있습니까? –

+0

구조체 내부에서 플래그라고하는 int 멤버를 만들면 구조체가 만들어 질 때마다 100으로 초기화됩니다. 그런 다음 구조체에 액세스 할 때마다 포인터를 사용하여 여전히 100을 사용하는지 여부를 확인합니다. 그래도 조각난 오류 인 경우 충돌을 피할 수있는 방법이 필요합니다. –

+0

과거에 작성 또는 관리 한 구조체에 대해 일반적으로 수행 한 작업은 구조체 멤버의 일부로 서명되지 않은 긴 집합 인 서명을 만드는 것입니다. 16 진수를 사용하는 특정 비트 패턴으로 변환합니다. 구조체에 대한 포인터를 끝내고 자유 또는 삭제를 수행하기 전에 모든 서명을 지울 것입니다. 그런 다음 포인터를 통해 구조체에 액세스 할 때 내가하는 일 중 하나는 서명이 올바른지 확인하는 것입니다. 그러나 이것은 다른 누군가의 코드에 의해 생성되고 관리되는 구조체에서는 작동하지 않습니다. –

5
당신이 모르는

때문에 :

  • 포인터는 단지 그것이 가리키는 객체의 주소를 포함;
  • 형식 정보가 컴파일 타임에 손실됩니다.

그래서 C는 이러한 종류의 문제를 처리 할 수있는 기능이 없으므로 스스로 가리키는 내용을 추적해야합니다.

구조체가 상주 할 메모리 페이지가 여전히 액세스 할 수 있는지 확인하는 것이 가장 많이 요구되는 사항이지만 (일반적으로 OS에 따라 다름) 일반적으로 특히 유용한 정보는 아닙니다.

1

코드를 작성하여 추적하는 것은 C의 책임입니다. 특별한 값인 NULL (아무 것도 가리 키지 않음)을 사용할 수 있으며, 사용하기 전에 &을 가리키는 포인터를 없애거나 설정할 때 포인터를 NULL로 설정하면 NULL을 사용할 수 있습니다. 질문이 나오지 않는 방식으로 코드를 디자인 할 수도 있습니다.

무작위 포인터 값을 쿼리하여 무언가를 나타내는 지 여부를 확인하는 방법은 없습니다. int 변수를 쿼리하여 초기화되지 않은 값, 정크 값 또는 올바른 결과를 확인하는 방법이없는 것처럼 계산.

소프트웨어 설계의 모든 문제이며, 필요한 경우 NULL 값을 사용하여 설정되지 않음을 지정합니다.

3

할당 패턴/행운에 따라 세그먼트 결함이 생길 수 있지만 (물론 프로그램을 죽이는) 적어도 그 참조는 더 이상 유효하지 않다는 것을 알려줄 것입니다.

그러나 앞에서 설명한 것처럼 가장 좋은 방법은 직접 유효성을 추적하는 것입니다.

구조체를 공백으로 유지하고 현재 위치에서 다시 초기화하지 않고 구조체를 계속 움직여야하는 경우 포인터를 포인터로 사용하여 쉽게 추적 할 수 있습니다.
"즉 모든 것이 구조체에 대한 포인터를 참조하고 구조체를 이동하거나 삭제할 때 포인터를 NULL 또는 새 메모리 위치로 설정하면됩니다."

또한, 일반적으로 프로그램에서 이런 종류의 이상한 점을 확인하려면 valgrind를 살펴 보는 것이 좋습니다.

+1

+1 포인터 - 포인터 제안. 성능에 중요한 코드에서는 캐시 문제가있을 수 있지만, 그렇지 않으면 지저분한 문제에 대한 합리적인 해결책입니다. 주목할 점은 포인터 배열에 대한 인덱스가 비슷하게 작동한다는 것입니다. – sfstewman

+0

좋은 의견입니다. :) – CasualT

관련 문제