C++ 개념 정리

16. std::list

CE : 하랑 2026. 1. 18. 16:26

 

C++ 스탠다드 라이브러리 (std) 안에 있는 스탠다드 템플릿 라이브러리(stl)에 포함된 시퀀스 컨테이너이며, 드 기반으로 데이터를 저장 하고 추가, 삭제가 용이한   특징이 있습니다.

 

 

std::vector와 std::list 의 차이점

 

std::vector는 다이렉트로 접근이 가능한 반면, std:: list는 다이렉트로 접근할 수 없습니다.

 

 

-  양방향 리스트 -> 그안에 존재하는 노드는 양방향 노드라고 부른다.

(1) erase

// 안전한 방법
startIter=testList.erase(startIter); 
// erase 함수의 리턴값이 바로 삭제 원소 다음에 있는 원소 iterator
// 즉 다음 노드를 가리킴

 

#include <iostream>
#include <map>
#include <list>
#include <vector>
#include <string>
#include <string_view>

class A
{
public:

    void test()
    {

        std::cout << "ㅎㅇㄹ" << "\n";
    }
};


int main()
{
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

    std::list<A*> testList;

    for (size_t i = 0; i < 3; i++)
    {
        A* a = new A();
        testList.push_back(a);
    }

    for (A* text : testList)
    {
        text->test();
    }

    std::list<A*>::iterator startIter = testList.begin();
    std::list<A*>::iterator endIter = testList.end();

    for (; startIter != endIter; )
    {
        A* fora = *startIter;
        fora->test();

        delete *startIter;
        *startIter = nullptr;
      /*  이를 위한 해결 방법

        가장 확실한 방법은 erase 함수의 리턴값을 이용하는 것이다.

       erase 함수의 리턴값이 바로 삭제 원소 다음에 있는 원소 iterator이기 때문...*/
        startIter=testList.erase(startIter); // 아 -> 이게 안전하게 리스트 삭제를 도와주는거인듯

        //++startIter; // 이게 왜됨?
    }

    // testList.clear(); 하는 거랑 동일

    sizeof(testList);

    int bb = 0;
}

 

 

- RangeFor -> 중간에 삭제를 못함

이유 ? 프로그램 터짐

-> /Rangedfor를 돌리는 동안 자료구조의 메모리 구조가 변경되면 // 치명적인 에러를 낼수 있다.

for (; StartIter != EndIter;)
{
	AActor* Actor = StartIter.operator*();

	if (nullptr == Actor)
	{
		MsgBoxAssert("Actor가 nullptr인 경우가 존재했습니다");
		return;
	}

	if (false == Actor->IsDestroy())
	{
		Actor->CheckReleaseChild();
		++StartIter;
		continue;
	}

	delete Actor;
	Actor = nullptr;
	StartIter = ActorList.erase(StartIter);
}

 

 


(2) list를  stack과 queue 처럼 사용해보기

 

- stack

#include <iostream>
#include <map>
#include <list>
#include <vector>
#include <string>
#include <string_view>

class A
{
public:

    void test()
    {

        std::cout << "ㅎㅇㄹ" << "\n";
    }
};

// 스택처럼 사용해보기 LIFO 나중에 들어온에가 먼저 나감
int main()
{
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

    std::list<A*> AStack;

    for (size_t i = 0; i < 3; i++)
    {
        A* a = new A();
        AStack.push_back(a); // 들어온 순서대로 쌓임
    }

    while (true)
    {
        if (AStack.size() == 0)
        {
            break;
        }

        AStack.back()->test(); // 제일 마지막에 있는 값

        // 동적할당한 메모리 정리
        delete AStack.back();
        AStack.back() = nullptr;

        AStack.pop_back(); // 마지막 노드 정리
    }

    sizeof(AStack); // size=0;

    int bb = 0;

}

 

- queue

#include <iostream>
#include <map>
#include <list>
#include <vector>
#include <string>
#include <string_view>

class A
{
public:

    void test()
    {

        std::cout << "ㅎㅇㄹ" << "\n";
    }
};

// 큐처럼 사용해보기 FIFO 선입선출
int main()
{
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

    std::list<A*> AStack;

    for (size_t i = 0; i < 3; i++)
    {
        A* a = new A();
        AStack.push_back(a); // 들어온 순서대로 쌓임
    }

    while (true)
    {
        if (AStack.size() == 0)
        {
            break;
        }

        AStack.front()->test(); // 제일 앞에 있는 값

        // 동적할당한 메모리 정리
        delete AStack.front();
        AStack.front() = nullptr;

        AStack.pop_front(); // 마지막 노드 정리
    }

    sizeof(AStack); // size=0;

    int bb = 0;

}

'C++ 개념 정리' 카테고리의 다른 글

18. 매크로 함수와 C++ 인라인 함수  (0) 2026.01.18
17. 컨테이너  (0) 2026.01.18
15. std::map  (0) 2026.01.17
14. string_view  (0) 2026.01.17
13. iterator  (0) 2026.01.17