2010-07-27 6 views
5

이것은 위법입니까/위험입니까?정적 변수 포인터?

int* static_nonew() 
{ 
    static int n = 5; 
    return &n; 
} 

컴파일러가 문제가있는 것 같지 않지만, 다른 사람이 메모리를 필요로 할 때 덮어 쓰지 보호 포인터 위치 자체가 무엇입니까?

편집 : 내가 왜이 질문을했는지에 대한 설명이 조금 더 있습니다. 참고 : 저는 C++로 프로그래밍하고 있습니다. C++로 질문하는 것보다 C 코드가 많아서 C로 태그를 붙였습니다.

정적 인지도를 반환해야하는 클래스가 있습니다. 이 맵을 여러 번 할 필요가없는 것처럼 프로그램 전체에 걸쳐이 맵을 한 번만 초기화하면됩니다. 이러한 이유 때문에 다음과 같은 것을 갖게되었습니다.

전환 클래스 생성자는 전환에 자신을 추가합니다. 그런 식으로 전환을 한 번 생성 한 다음 포인터를 반환합니다. 스택에 할당 된 변수에 대한 참조를 만들면 매우 쉽게 덮어 쓸 수 있으며 "안전하지 않음"이라는 것을 기억합니다. 함수 내에서 생성 된 정적 변수가 정확히 어떻게 작동하는지 정확하게 알지 못했습니다.

+0

지도가 클라이언트 코드에 의해 변경 될 것으로 예상되지 않으면 const 참조 또는 const에 대한 포인터를 반환해야합니다. 그러면 정적 데이터와 관련된 대부분의 위험이 제거됩니다. –

답변

5

이것은 유효한 코드이며 유용합니다.

많은 싱글 톤 팩토리가 이와 같이 구성됩니다.

6

이것은 정적 변수의 포인터에 대한 get 함수입니다. 그것에 대해 불법은 없습니다. 다른 유형의 정적 데이터보다 본질적으로 위험하지 않습니다.

그러나 정적 데이터 :

  1. 종종 약한 디자인의 표시이다 미묘한 버그 기회를 만들어 꽉 커플 링을
  2. 지장을 초래할 재진입을 생성
  3. 매우 사용되어야한다 현명하게

정적 저장소 클래스 수정자는 메모리가 프로세스 수명 동안이 변수에 예약되어 있음을 의미합니다. 당신이 통과하면

+0

+1 : 멀티 스레드 문제 (re-entrancy)에 대해 언급 한 유일한 대답 – smerlin

+0

+1 : 불법은 아니지만 위험합니다. – Puppy

-1

당신이 어떤 메모리 위치에 대한 포인터를 반환 한 후에는 int* static_nonew()

을 의미 한 가정하면, 그 메모리를 덮어 쓸 수, C.에는 보호 보장,

또한 없다 free이 포인터는 동작이 정의되지 않은 경우가 있으므로 때로는 정상이되며 때로는 코어를 덤프합니다.

반면에 이것은 완전히 합법적 인 코드입니다. 또한 int을 약간의 struct으로 대체하면 한 번 초기화해야하며 매우 유용한 관용어입니다.

+0

"때로는 괜찮을 것입니다."매우 오도하는 것입니다. ** ** 괜찮아 보이더라도 위험한 메모리 손상 가능성이 있습니다. –

+0

@R .. 전체 문장을 읽을 수 있습니까? 코어 덤프라고하면 위험하다고 생각합니다. 그리고 행동이 정의되지 않기 때문에 때로는 실제로 부작용이 없습니다. –

1

이것은 합법적이지만 전환의 인스턴스가 하나 뿐이며 static으로 선언되었으므로 main()보다 먼저 생성된다는 것을 기억하십시오. 그것은 꽤 글로벌 변수를 갖는 것과 같습니다.