5

'next'포인터가 스마트 포인터 인 링크 된 목록과 같은 간단한 데이터 구조. 헤드 노드가 삭제되면 스마트 포인터 '다음'이 실행되고 재귀 적 삭제가 수행됩니다. 긴 목록의 경우 스택을 빠르게 날려 버립니다.스마트 포인터가 재귀 적 삭제로 인해 스택을 휩쓸습니다.

나는 이러한 스마트 포인터를 단순한 원시 포인터로 대체해야했다. 내가 여기서 뭔가를 놓치고 있니?

+0

'블로킹 스택'? 제발 정교하게 만들어 줄 수 있어요. – Flexo

+2

거의 확실하게 이것은 스마트 포인터의 잘못이 아닙니다. 몇 가지 코드를 보여 주면 구현에 버그가 될 수 있습니다. 어떤 경우 든, 완전한리스트 삭제는 재귀가 아닌 반복에 의한 것이어야하므로, 일정한 스택 공간을 가져야한다. –

+1

@Kerrek : 스마트 포인터의 소멸자가 pointee를 삭제합니다. pointee가 다른 스마트 포인터를 포함하고 있으면 재귀를 발생시킵니다. 필자는 스마트 포인터를 어떻게 피할 수 있는지 보지 못합니다. –

답변

5

. '오래된'머리가 삭제되고 기존의 2 위 항목이 머리로 승격됩니다. 하나의 일관된 변화 속에서 깊은 재귀가 없습니다. 이것에 대한 유일한 전제 조건은 머리가 NULL이 아니라는 것입니다.

마이크가 전체 목록을 삭제하는 것이 목표 인 경우 의견에서 지적했듯이 루프 내에서 반복 할 수 있습니다.

+3

그렇습니다. 따라서 전체 목록을 'while (head) head = head-> next;'로 반복적으로 삭제할 수 있습니다. –

+1

누군가가 WTF에 올 것이므로 코멘트를 잊지 마세요 :) – UncleBens

+0

" 머리는 삭제되고 오래된 두 번째 항목은 머리로 승격됩니다. "- 그 진술은 무슨 일이 일어나고 있는지를 반영하면서 놀라운 단순화입니다. 평범한 독자가 언어 역학과 스마트 포인터 기능에 정통한 경우가 아니라면이 솔루션은 효과가 있지만 다른 어떤 것보다 더 마술 적입니다. 그리고 그들이 익숙한 사람이라면, 처음에는 그것을 필요로하지 않을 것입니다. 그 간단한 'head = head-> next'지정 과정에서 발생한 일이 정확히 무엇인지를 단계별로 살펴보면 * 크게 * 분명해집니다. – WhozCraig

2

링크 된 목록 클래스의 내부에있는 스마트 포인터가 당신을별로 사지 않는 것 같습니다. 원시 포인터가 내게 완벽하게 합리적인 것 같습니다. 나는 똑똑한 포인터가 무언가를 삭제하는 것을 잊어 버리는 것이 쉬운 통제가 덜 된 상황에 가장 잘 사용된다고 생각한다.

스택을 날려 버릴 엄청난 목록 이었음에 틀림 없다. 코드에 버그가 없으 셨겠 니?

head = head->next; 

또는 동등 : 나는 당신이 바로 이해했습니다 모두 headnext 당신이 수행하여이 문제를 피할 수 있습니다 스마트 포인터 가정

+0

내부에서 스마트 포인터를 사용하면 더 높은 예외 안전 보장을받을 수 있습니다. 노동력면에서 무료이며 추가 저장 비용은 거의 없습니다. 그것만으로 나에게 가치있는 것 같다. – Flexo

+0

네, 공정한 부분입니다. – john

+0

글쎄, 스마트 포인터를 사용하여 새로 만든 노드가 목록에 첨부되기 전에 보유합니다. 그러나 일단 연결되면 목록 노드의 소멸자의 책임입니다. 아시다시피, 필자는 어쨌든 자동 스마트 포인터 재귀를 손으로 코딩 된 반복으로 대체하기 위해 소멸자에서 수동 처리를 수행해야합니다. 예외 안전 문제에 대해 자세히 설명해 주시겠습니까? 소멸자의 처리되지 않은 예외가 스마트 포인터에 상관없이 어쨌든 프로그램을 죽일 것이라고 생각했습니다. – Jay