C++의 경우 스택을 사용하는 것이 가장 좋습니다. 언제 힙을 사용하는 것이 가장 좋습니까?힙 대신 스택을 사용하는 것이 가장 좋으며 그 반대도 마찬가지입니까?
답변
현재 함수가 반환 된 후에 변수를 사용하지 않을 때 스택을 사용하십시오. 변수의 데이터가 현재 함수의 수명 이상으로 필요할 때 힙을 사용하십시오.
그걸 해결할 방법이 있습니다. 버퍼에 데이터를 쓰는 함수에 버퍼를 전달하는 것은 하위 스택 프레임에있는 동적 데이터를 "반환"하는 함수를 만드는 좋은 방법입니다. OO와 비슷하지만 훨씬 효율적입니다. –
크기 또한 고려 사항입니다. 스택의 1K가 넘는 항목은 신중하게 고려해야합니다. 때로는 힙 메모리에 스택 포인터를 두는 것이 더 좋습니다 ('Resource Acquisition is Initialization'관용구와 함께) – Arkadiy
하지만 메모리가 클래스의 속성 인 경우 클래스 속성이 포인터가 될지 또는 그렇지 않으면 언제 결정해야합니까? 또한 언제 스마트 포인터를 사용할 수 있습니까? – JagWire
런타임시 오브젝트에 대한 공간 만 할당하기 위해 힙을 사용하십시오. 컴파일 할 때 크기를 알고 있으면 스택을 사용하십시오. 함수에서 힙 할당 객체를 반환하는 대신 함수에 버퍼를 전달하여 쓰기 권한을 부여합니다. 그런 식으로 함수가 배열이나 다른 스택 기반 구조로 호출되는 곳에 버퍼를 할당 할 수 있습니다.
더 적은 malloc() 문을 사용하면 메모리 누수 가능성이 줄어 듭니다.
이 질문은 며칠 전 물어 본 What and where are the stack and heap과 관련이 있습니다.
질문이 잘못되었습니다.
스택이 필요한 상황, 힙이 필요한 곳, 정적 저장소가 필요한 곳, const 메모리 데이터가 필요한 곳, 무료 저장소가 필요한 곳 등이 있습니다.
할당은 SP를 통한 "증가"이므로 모든 "할당"은 현재 함수의 호출 시간에 수행되기 때문에 스택이 빠릅니다. 힙 (또는 무료 저장) 할당/할당 해제는 더 많은 시간입니다 비싸고 오류가 발생하기 쉽다.
엄지 손가락으로 말하면, 스택에 거대한 물건을 만들지 마십시오.
- 스택에 개체를 만들면 개체를 정리 (읽기 삭제)해야한다는 부담을 덜어줍니다. 그러나 스택에 너무 많은 객체를 만들면 스택 오버플로 가능성이 높아집니다.
- 개체에 힙을 사용하면 OS가 제공 할 수있는만큼의 메모리를 얻을 수 있습니다. 스택보다 훨씬 넉넉하지만, 완료되면 다시 메모리를 확보해야합니다. 또한 힙에 너무 많은 객체를 너무 자주 만들면 메모리가 조각 나게되어 응용 프로그램의 성능에 영향을 미칩니다.
사용중인 메모리가 작성중인 범위에 엄격히 제한되어있을 때 스택을 사용하십시오. 이는 메모리 누수를 피하기 위해 유용합니다. 왜냐하면 메모리를 어디서 사용하고 싶은지 정확히 알기 때문에 더 이상 필요없는 시점을 알기 때문에 메모리가 정리됩니다.
int main()
{
if (...)
{
int i = 0;
}
// I know that i is no longer needed here, so declaring i in the above block
// limits the scope appropriately
}
그러나 힙은 메모리가 작성 범위를 벗어나 액세스 될 수 있고 스택 변수를 복사하지 않으려는 경우에 유용합니다. 이렇게하면 메모리 할당 및 할당 해제 방법을 명시 적으로 제어 할 수 있습니다.
Object* CreateObject();
int main()
{
Object* obj = CreateObject();
// I can continue to manipulate object and I decide when I'm done with it
// ..
// I'm done
delete obj;
// .. keep going if you wish
return 0;
}
Object* CreateObject()
{
Object* returnValue = new Object();
// ... do a bunch of stuff to returnValue
return returnValue;
// Note the object created via new here doesn't go away, its passed back using
// a pointer
}
명백히 일반적인 문제는 개체를 삭제하는 것을 잊어 버릴 수 있다는 것입니다. 이를 메모리 누수라고합니다. 이러한 문제는 "소유권"(또는 사물을 삭제할 책임이있는 사람)이 정의하기가 더 어려워지는 프로그램이 점점 줄어들면서 점점 더 널리 퍼지고 있습니다.
더 많은 관리 언어 (C#, Java)의 일반적인 솔루션은 가비지 수집을 구현하므로 삭제할 필요가 없습니다.그러나 이것은 배경에 힙 데이터를 검사하기 위해 비 주기적으로 실행되는 무언가가 있음을 의미합니다. 평범하지 않은 프로그램에서는 "가비지 콜렉션"스레드가 튀어 나오고 떼어 내고 삭제해야하는 데이터를 찾고 나머지 프로그램은 실행이 차단되어 다소 비효율적이 될 수 있습니다.
C++에서 메모리 누출 문제를 해결하는 가장 일반적인 방법은 스마트 포인터를 사용하는 것입니다. 이 중 가장 일반적인 것은 boost::shared_ptr이고 (reference counted)
위 예제를 다시 작성하려면 boost :: shared_ptr CreateObject();
int main()
{
boost::shared_ptr<Object> obj = CreateObject();
// I can continue to manipulate object and I decide when I'm done with it
// ..
// I'm done, manually delete
obj.reset(NULL);
// .. keep going if you wish
// here, if you forget to delete obj, the shared_ptr's destructor will note
// that if no other shared_ptr's point to this memory
// it will automatically get deleted.
return 0;
}
boost::shared_ptr<Object> CreateObject()
{
boost::shared_ptr<Object> returnValue(new Object());
// ... do a bunch of stuff to returnValue
return returnValue;
// Note the object created via new here doesn't go away, its passed back to
// the receiving shared_ptr, shared_ptr knows that another reference exists
// to this memory, so it shouldn't delete the memory
}
그리고 나서 move-semantics가있었습니다. –
가능한 한 언제든지 스택을 사용하십시오. 변수가 그 범위 밖에서 절대로 필요하지 않을 때.
더 빠르면 조각화가 덜 일어나고 malloc 또는 new를 호출하는 것과 관련된 다른 오버 헤드가 발생하지 않게됩니다. 스택을 할당하는 것은 몇 가지 어셈블러 연산입니다. malloc 또는 new는 효율적인 구현에서 수백 줄의 코드입니다.
힙을 사용하는 것이 절대로 좋지 않습니다 ... 단지 피할 수없는 것입니다. :)
당신은 함수의 범위를 벗어난 필요하지 않은 지역 변수에 대한 스택을 사용하여 일반적으로해야 그 위에서 언급 한 규칙의 예외 : 그들은 지역의 대형 할당 할 경우
재귀 함수는 스택 공간을 소모 할 수 있습니다 변수 또는 재귀 적으로 여러 번 호출되는 경우. 메모리를 사용하는 재귀 함수가있는 경우 스택 기반 메모리 대신 힙 기반 메모리를 사용하는 것이 좋습니다.
- 1. NetBeans는 Eclipse 프로젝트와 잘 작동합니까? 그 반대도 마찬가지입니까?
- 2. MATLAB이 SCILAB보다 어떤 이점을 가지고 있으며 그 반대도 마찬가지입니까?
- 3. ClearCase : Unix에서 생성 된 뷰는 Windows에서 볼 수 없으며 그 반대도 마찬가지입니까?
- 4. 자바에서 IM을 위해 mjsip 스택을 사용하는 것이 가능합니다.
- 5. ViewModels 대신 ViewData를 사용하는 것이 언제 올바른가요?
- 6. izip 대신 zip을 사용하는 것이 더 좋은가요?
- 7. 팝업 텍스트 대신 Sprites 대신 Labels를 사용하는 것이 더 낫습니다.
- 8. 컨트롤러의 UrlHelper 매개 변수를 사용하는 확장 메서드에 액세스 할 수 없습니다! 보기에서 그 반대도 마찬가지입니다.
- 9. 언어를 사용하는 대신 시스템의 기능을 사용하는 것이 더 좋을까요?
- 10. 이 예제는 인덱스를 사용하는 것이 가장 좋습니다
- 11. ViewState 또는 hiddenfield를 사용하는 것이 가장 좋습니다
- 12. 파일 발송자에 타이머를 사용하는 것이 가장 좋습니까?
- 13. ANTLR과 같은 파서를 사용하는 것이 가장 좋습니다.
- 14. Visual Studio에서 Git을 사용하는 것이 가장 좋습니다.
- 15. 데이터베이스 대신 정적 개체를 사용하는 것이 좋지 않습니까?
- 16. 새로운 RijndaelManaged() 대신 Rijndael.Create()를 사용하는 것이 안전합니까?
- 17. 기존 클래스에 추가하는 대신 새로운 클래스를 사용하는 것이 가장 좋은 경우
- 18. 레코드 대신 연결 목록을 사용하는 것이 좋은 생각입니까?
- 19. 동기화를 위해 공유 잠금 대신 로컬 잠금을 사용하는 것이 안전합니까?
- 20. 힙 영역 만 사용하는 재귀
- 21. malloc.c를 사용하는 힙 할당 메모리 범위
- 22. 스택을 반전하여 ArrayList에 추가하는 가장 효율적인 방법
- 23. 화살표 이미지 대신 htmlentities에서 화살표를 사용하는 것이 현재 "안전"합니까?
- 24. Java에서 배열 대신 목록을 사용하는 것이 바람직한 이유는 무엇입니까?
- 25. C#에서 이름 앨리어싱 대신 상속을 사용하는 것이 맞습니까?
- 26. 델파이의 모달 폼에서 Release 대신 Free를 사용하는 것이 안전합니까?
- 27. PDO 대신 Doctrine 2를 사용하는 것이 어떤 조건에서 가능합니까?
- 28. AtomicBoolean 대신 Java에서 volatile 휘발성을 사용하는 것이 바람직한 경우는 언제입니까?
- 29. SDL 블리 팅 기능 대신 OpenGL을 사용하는 것이 합리적입니까?
- 30. 데이터 바인딩 대신 DataTrigger를 사용하는 것이 더 좋습니까?
데이터 구조 힙과 스택이 아니라 메모리를 할당하기위한 시스템 스택과 시스템 힙을 의미한다고 생각하십니까? –