🤍 전 강의 25% 할인 중 🤍

2024년 상반기를 돌아보고 하반기에도 함께 성장해요!
인프런이 준비한 25% 할인 받으러 가기 >>

  • 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    미해결

Static UserManager um을 포인터로 만들어서 리턴 하면 안되는 이유가 궁금합니다.

24.05.20 23:55 작성 조회수 85

0

아래의 코드와 같이 포인터로 변수를 만들어줘서 넘겨주면 AddUser() 함수를 부를때 '_userCount' 올려주는 변수에서 '액세스 위반 this가 nullptr 입니다.' 라고 뜹니다.

그 이유가 객체를 생성해 주지 않았기 때문에 'nullptr'이 생성 되는 건가요?

이해가 잘 되지 않는 부분이 static 함수를 부를 때 변수를 초기화 되어 전역 변수로 사용되는데, 포인터는 객체가 생성되지 않는 것 같더라구요.

그래서 new UserManager( ) 를 통해 동적 할당을 하니 객체가 하나씩 생기는 문제가 발생하고, static 메모리와 동적 할당 되는 메모리 위치(?), 특성(?)이 달라서 생기는 문제인가 싶습니다.

public:
	UserManager() :_userCount(0) {}
	static UserManager* GetInstance()
	{
		static UserManager* um = new UserManager();
		um->_userCount = 0;
		return um;
	}

 

주저리 주저리 궁금한 내용을 적다보니 제대로 설명했는지 모르겠네요... ㅡㅜ

답변해 주신다면 감사하겠습니다.

 

혹시 몰라 _userCount를 생성자로 초기화 시켜줬습니다.

class UserManager
{
public:
	UserManager() :_userCount(0) {}
	static UserManager* GetInstance()
	{
		static UserManager* um = nullptr;
		return um;
	}

public:
	void AddUser() { _userCount++; }
	int GetUserCount() { return _userCount; }

private:
	int _userCount = 0;

};

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.05.23

안녕하세요, 인프런 AI 인턴입니다.

UserManager 클래스의 GetInstance 메서드에서 nullptr을 반환하는 문제에 대해 질문하셨군요. 문제의 핵심은 GetInstance 메서드에서 um 포인터를 nullptr로 초기화하고 그대로 반환하기 때문입니다. 이 때문에 GetInstance를 통해 반환받은 포인터는 실제 UserManager 객체를 가리키지 않게 됩니다. 따라서, 이 포인터를 사용하여 AddUser 같은 멤버 함수를 호출하려 하면, _userCount 변수에 접근하는 과정에서 “액세스 위반 this가 nullptr 입니다.“라는 오류가 발생합니다.

이 문제를 해결하기 위해서는 GetInstance 메서드 안에서 실제 UserManager 객체를 생성하고, 이 객체를 가리키는 포인터를 반환해야 합니다. 이를 위해 싱글턴 패턴에서 자주 사용되는 방식 중 하나는, static 지역 변수를 사용하는 것입니다. static 지역 변수는 처음 함수가 호출될 때 한 번만 초기화되며, 프로그램 종료 시까지 메모리에 남아있습니다. 아래 코드 예제와 같이 수정하면, UserManager의 인스턴스를 안전하게 생성하고 관리할 수 있습니다.

class UserManager
{
public:
    UserManager() : _userCount(0) {}
    static UserManager* GetInstance()
    {
        static UserManager um; // 객체를 static 지역 변수로 생성
        return &um; // um의 주소 반환
    }

public:
    void AddUser() { _userCount++; }
    int GetUserCount() { return _userCount; }

private:
    int _userCount = 0;
};

위와 같이 수정하면, GetInstance 메서드를 통해 UserManager의 유일한 인스턴스에 접근할 수 있게 됩니다. 이 방식은 싱글턴 디자인 패턴의 일반적인 구현 방법 중 하나입니다. static 지역 변수를 이용하면 파괴자도 자동으로 호출되기 때문에 메모리 관리 측면에서도 안전합니다.

채널톡 아이콘