2017-10-26 2 views
-1

어떤 이유로 든 프로그램에서 동적 메모리 할당을 사용하지 않기로했습니다. 이것은 내 프로그램의 모든 변수가 정적이고 "새로운"생성자가 사용되지 않는다는 것을 의미합니다. 그러나 다음 코드는 충돌 및 스택 오버 플로우 예외 발생 : 내가하고 싶은 모든주고 X 자신과 다른 많은 변수를 포함하는 구조이다 VeryLargeObject의 기본값입니다, 분명히생성자가 항상 스택에서 호출되는 이유는 무엇입니까?

VeryLargeObject x; // Global variable -> static memory 

void ResetTheObject() 
{ 
    x = VeryLargeObject(); 
} 

을 다양한 복잡성을 가진 생성자 (초기화 작업이 상당히 필요함). 하지만 여기서 언어/컴파일러는 복사하기 전에 스택에서이 작업을 수행해야한다고 결정했으며 VeryLargeObject가 스택에 비해 너무 크기 때문에 프로그램이 중단됩니다. 나는이 문제에 대한 해결책을 발견했다 그러나

는 :

VeryLargeObject x; 

void ResetTheObject() 
{ 
    new (&x) VeryLargeObject(); 
} 

내가 전에 들어 본 적이없는, 아직 내가 원하는 정확히 않습니다. 이것은 "새로운 배치"입니다. 그것은 포인터에 의해 제공되는 이미 할당 된 (또는 단순히 정적 인) 메모리에서 생성자를 호출합니다.

제 질문은 해결책이 있기 때문에 호언 장담 : 왜 이것이 첫 번째 코드의 기본 동작이 아닙니까? 이 일을 덜 해킹하는 방법이 없다면 (즉, "new"라는 단어가 없어도 상관 없습니다), 그 이유는 무엇입니까? 또한 방금 제공 한 이유는 포인터를 다시 보내는 이유는 무엇입니까? 나는 C++이 훌륭한 언어라고 생각했지만, 이것은보기 흉하고 잘 못된 것 같습니다.

+2

"어떤 이유로 든 프로그램에서 동적 메모리 할당을 절대로 사용하지 않기로했습니다." "나는 C++이 훌륭한 언어라고 생각했지만, 이것은보기 흉한 것 같고 잘 못된 것 같습니다." 너는 그들에게 btw btw 보이지 않니? – Slava

+5

"* 이것은 내 프로그램의 모든 변수가 정적이라는 것을 의미합니다. *"아니, *는 * 의미하지 않습니다. 당신은 정말로 전역의 부하를 원하지 않습니다. – juanchopanza

+4

그런 식으로 새 게재 위치를 사용하지 않아야합니다. 먼저 소멸자를 호출하여 원래의 객체를 파괴해야합니다. –

답변

1

우선 최적화를 사용하면 첫 번째 구문으로 원하는 것을 얻을 수 있습니다. 컴파일러가 없으면 컴파일러에 다음과 같이 요청했습니다.

  1. VeryLargeObject 임시 개체를 만듭니다.
  2. x이라는 전역 변수에 할당하십시오.

임시 개체는 저장소가 필요하므로 컴파일러는 스택에 개체를 할당합니다. 컴파일러가 수행하는 작업은 문자 그대로 컴파일러에게 수행하도록 요청한 작업입니다.

최적화 프로그램이 켜져 있으면 컴파일러에서 시퀀스가 ​​무엇인지 이해하고 복사본을 저장할 수 있습니다. 이것은 컴파일러가 이전 값인 x이 어떤 식 으로든 방해가되지 않는다는 것을 확실하게 증명할 수 있어야합니다. 초기화가 꽤 복잡하다는 것을 인정하기 때문에, 컴파일러가 그렇게하지 않으면 컴파일러를 용서할 수 있습니다.

두 가지 옵션이 있습니다. 내부 초기화 함수를 생성하고 생성자 대신 호출 할 수도 있고 그렇지 않은 경우와 마찬가지로 새로 배치를 사용할 수도 있습니다.

배치를 새로 사용할 때 위험한 점은 적절하게 파괴하지 않고 x의 이전 값을 대체한다는 것입니다. x이 초기화되지 않은 것으로 가정합니다. 그래도 괜찮 으면 사용하고 사용하십시오. 컴파일러는 그 부분을 고려하여 허용하지 않습니다.

+1

'x '가 POD이면 괜찮습니다. 가장 안전한 방법은 배치 인스턴스를 새로 작성하기 전에 이전 인스턴스에서 소멸자를 호출하는 것입니다. POD 인 경우 소멸자는 어쨌든 빈 작업 일 것입니다. 그렇지 않다면 전화 해 주셔서 감사합니다. –

+0

최적화가 도움이 될 수 있다고 생각했지만 O2에서 O4로 바뀌 었습니다. 사실 VeryLargeObject는 초기화 할 객체가 너무 많아서 컴파일러가 아무것도 최적화되지 않았는지 확인하기가 너무 게을립니다. – demanze

관련 문제