inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part1: C++ 프로그래밍 입문

list #3

함수가 끝나는 시점에서 크래쉬가 나요!

377

황경훈

작성한 질문수 12

0

#include <iostream>

using namespace std;

#include <list>

//양방향 리스트, 링크드 리스트.
template<class T>
class Node {

public:
	Node() : _next(nullptr), _prev(nullptr), _data(T()) {

	}
	Node(const T& value) : _next(nullptr), _prev(nullptr), _data(value)
	{

	}

public:
	Node* _next;
	Node* _prev;
	T _data;
};


template<class T>
class Iterator
{
public:
	Iterator() : _node(nullptr)
	{

	}
	Iterator(Node<T>* data) : _node(data) {

	}

	Iterator<T>& operator++()
	{
		_node = _node->_next;
		return *this;
	}
	Iterator<T> operator++(int)
	{
		Iterator<T> temp = *this;
		_node = _node->_next;
		return temp;
	}

	Iterator<T>& operator--() {
		_node = _node->_prev;
		return *this;
	}
	Iterator<T> operator--(int)
	{
		Iterator<T> temp = *this;
		_node = _node->_prev;
		return temp;
	}
	T& operator*()
	{
		return _node->_data;
	}
	bool operator==(const Iterator& right)
	{
		return _node == right._node;
	}
	bool operator!=(const Iterator& right)
	{
		return !(*this == right);
	}

public:
	Node<T>* _node;
};


//[1]->[2]->[3]->[4]->[header]가 빈 깡통이어도 기본 
template<class T>
class List {

public:
	typedef Iterator<T> iterator;
	List() :_size(0)
	{
		_header = new Node<T>();
		_header->_next = _header;
		_header->_prev = _header;
	}
	~List() {
		//TODO
		while (_size > 0)
			pop_back();

		delete _header;
	}
	void push_back(const T& value)
	{
		AddNode(_header, value);
	}
	// [1] <-> [2] <-> 3 <->[header]
	// [1] <-> [2] <-> [ header ] 
	void pop_back()
	{
		RemoveNode(_header->_prev);
	}
	iterator insert(iterator iter, T _data)
	{
		return iterator(AddNode(iter._node, _data));
	}
	iterator erase(iterator iter)
	{
		Node<T>* target = RemoveNode(iter._node);
		return iterator(target);
	}
private:
	Node<T>* AddNode(Node<T>* before, const int& value)
	{
		Node<T>* newNode = new Node<T>(value);
		Node<T>* prevNode = before->_prev;

		prevNode->_next = newNode;
		newNode->_next = before;

		before->_prev = newNode;
		newNode->_prev = prevNode;

		++_size;
		return newNode;
	}
	Node<T>* RemoveNode(Node<T>* target)
	{
		Node<T>* prevNode = target->_prev;
		Node<T>* nextNode = target->_next;

		prevNode->_next = nextNode;

		nextNode->_prev = prevNode;

		--_size;


		delete target;
		return nextNode;
	}

public:
	iterator begin() { return iterator(_header->_next); }
	iterator end() { return iterator(_header); }

	int size() { return _size; }
public:

	Node<T>* _header;
	int _size;
};

template<class T>
void test(T);
int main() {

	/*List<int> li;
	List<int>::iterator eraseIt;

	for (int i = 0; i < 10; i++)
	{
		if (i == 5) {
			eraseIt = li.insert(li.end(), i);
		}
		else
		{
			li.push_back(i);
		}
	}

	li.pop_back();
	li.erase(eraseIt);
	for (auto i = li.begin(); i != li.end(); ++i)
	{
		cout << *i << endl;
	}*/

	test(List<int>());

}

template<class T>
void test(T) {
	T li;
	T::template iterator eraseIt;

	for (int i = 0; i < 10; i++)
	{
		if (i == 5) {
			eraseIt = li.insert(li.end(), i);
		}
		else
		{
			li.push_back(i);
		}
	}

	li.pop_back();
	li.erase(eraseIt);
	for (auto i = li.begin(); i != li.end(); ++i)
	{
		cout << *i << endl;
	}

}

 

해당 코드에서 main에서 주석으로 처리한 부분은 잘 되는데 template로 작성한 펑션이 끝나면 Invalid address specified to RtlValidateHeap 크래쉬가 나는데 이유가 궁금합니다.. ㅠ

C++

답변 1

1

Rookiss

리스트를 연습용으로 한 것이라 완전하지 않고
operator= 등의 복사에 대한 처리가 안 되어 있습니다.

test(List<int>());
여기서 임시 리스트를 만들어서 복사를 하고 있는데
그럴 경우 기본 헤더와 size 등이 [얕은 복사]로 넘어가서
동일한 헤더를 두 번 지우게 됩니다.

template<class T>
void test(T& li); 로 해서 왼값을 넘기거나
void test(T&& li); 로 해서 오른값을 넘기는 식으로 수정하시면 됩니다.

visualstudio에서 파일분할관리실습시 설정 문의를 드립니다.

0

548

1

정렬함수 좀 더 확실하게 이해 할 방법이 있을까요?

0

445

1

strcpy() 구현 관련 질문

0

519

1

빌드(망치)를 누르니 이런 오류가 떴습니다. 어떻게 해야 하나요?

0

461

1

클래스 타입의 포인터 질문합니다

0

551

1

입력값을 enum 값에 넣어주는거 이제 막혔나요?

0

502

1

템플릿 특수화 관련 질문

0

387

1

포인터 관련 질문합니다!

0

267

1

Unable to start assembler. Check your settings.

0

840

2

cpu선택

0

544

1

포인터 질문이 있습니다

0

330

1

20:35 에서 구조체 크기에 대한 질문입니다!

0

589

1

iterator 삭제관련

0

410

1

함수 호출을 디스어셈블러로 분석하다가 궁금점이 생겼습니다!

0

315

1

15 분 45초 대 질문

0

312

0

스택 프레임 질문합니다!

2

310

1

오른값 참조 in 게임

0

388

0

동적할당 질문이 있습니다

0

454

1

안녕하세요 메모리에 대해 질문드립니다.

0

310

1

함수객체 의 매개변수

0

365

1

복사생성자

0

439

1

main이나 endl 부분이 주황색으로 표시된건 어떻게 하나요

0

426

1

포인터 실습 강의를 보고 궁금한게 있습니다.

0

358

1

스택 오버플로우

2

795

1