본문 바로가기

숙제

C++ 숙제(메모리 누수 발생 코드 분석하고 보완하기, 스마트 포인터를 활용한 로그분석기 구현)

숙제 1. 메모리 누수 발생 코드 분석하고 보완하기

C++로 구현된 코드를 분석해서 메모리 누수가 우려되는 부분을 확인한 후, 코드를 수정하세요.

// 메모리 누수가 발생하는 코드

#include <iostream>
using namespace std;

class MyClass {
private:
    int* ptr;

public:
    // 생성자
    MyClass() {
        ptr = new int(10); // 동적 메모리 할당
        cout << "메모리 할당 완료!" << endl;
    }

    // 소멸자
    ~MyClass() {
      
    }

    void print() const {
        cout << "값: " << *ptr << endl;
    }
};

int main() {
    MyClass obj;
    obj.print();

    // main 함수 종료
    return 0;
}

#include <iostream>
using namespace std;

class MyClass
{
private:
    int* ptr;

public:
    // 생성자
    MyClass()
    {
        ptr = new int(10); // 동적 메모리 할당
        cout << "메모리 할당 완료!" << endl;
    }

    // 소멸자
    ~MyClass()
    {
        delete ptr; // 소멸 시에 동적 메모리 할당 했던거 해제함.
    }

    void print() const
    {
        cout << "값: " << *ptr << endl;
    }
};

int main() {
    MyClass obj;
    obj.print();

    // main 함수 종료
    return 0;
}

소멸자에 delete ptr;을 추가했다.

숙제 2 : 스마트 포인터를 활용한 로그분석기 구현

로그 기록기는 프로그램에서 발생한 중요한 사건을 기록합니다. 로그 기록기의 몇 가지 기능을 구현해 봅시다.

요구사항은 아래와 같습니다.

1. 로그 메시지는 중요도에 따라(Info, Warning, Error)로 분류되어 기록될 수 있습니다.

로그 앞에 중요도가 태그가 붙어 표시됩니다.

  • [Info] 사용자 메시지
  • [Warning] 사용자 메시지
  • [Error] 사용자 메시지

2. 로그 기록기는 단 하나의 인스턴스만 존재해야 하며, unique_ptr를 통해 이를 보장해야 합니다.

3. 지금까지 기록된 로그의 총개수를 출력할 수 있어야 합니다.


#include <iostream>

using namespace std;

class Logger
{
private:
	// 기록된 로그의 총 개수를 카운트 할 변수
	int logCount = 0;

public:

	void logInfo()
	{
		cout << "[INFO]: System is starting." << endl;
		logCount++; // 로그 출력시 로그 카운트 +1
	}

	void logWarning()
	{
		cout << "[WARNING]: Low disk space." << endl;
		logCount++; // 로그 출력시 로그 카운트 +1
	}

	void logError()
	{
		cout << "[ERROR]: Unable to connect to the server." << endl;
		logCount++; // 로그 출력시 로그 카운트 +1
	}

	void showTotalLogs()
	{
		cout << "Total logs recorded: " << logCount << endl;
	}

	~Logger() // 소멸자
	{
		cout << "Logger instance destroyed." << endl;
	}
};

int main()
{ // Logger 객체를 관리하는 유니크포인터 메세지 타입의 변수 Infomessage를 생성.
	unique_ptr<Logger> Infomessage = make_unique<Logger>();
	
	Infomessage->logInfo();

	// Warningmessage 변수로 소유권 이전, Infomessage는 비워짐.
	unique_ptr<Logger> Warningmessage = move(Infomessage);

	Warningmessage->logWarning();

	// Errormessage 변수로 소유권 이전, Warningmessage는 비워짐.
	unique_ptr<Logger> Errormessage = move(Warningmessage);

	Errormessage->logError();

	//지금까지 기록된 로그의 총 개수를 출력할 수 있어야 한다.
	Errormessage->showTotalLogs();

	return 0;
}

지금까지 모르는 것들을 인터넷 검색이나 코드를 잘 아는 친구에게 물어보며 풀었는데 이번에는 처음부터 끝까지 인터넷이나 친구의 도움없이 작성한 코드인데 답지를 보니 메인함수에서 소유권 이전은 할 필요가 없었단 것을 깨달았고 memory와 string도 포함이 안됐는데 어찌됐든 숙제에서 요구했던 로그 출력 예시처럼 실행은 되긴 한다.

 

아래는 답지이다.

// 숙제 답지

#include <iostream>
#include <memory>
#include <string>

using namespace std;

class Logger {
private:
    int logCount; // 총 로그 개수

public:
    // 생성자
    Logger() : logCount(0) {}

    // 일반 정보 로그
    void logInfo(const string& message) {
        logCount++;
        cout << "[INFO]: " << message << endl;
    }

    // 경고 로그
    void logWarning(const string& message) {
        logCount++;
        cout << "[WARNING]: " << message << endl;
    }

    // 에러 로그
    void logError(const string& message) {
        logCount++;
        cout << "[ERROR]: " << message << endl;
    }

    // 총 로그 개수를 보여주는 함수
    void showTotalLogs() {
        cout << "Total logs recorded: " << logCount << endl;
    }

    // 소멸자
    ~Logger() {
        cout << "Logger instance destroyed." << endl;
    }
};

int main() {
    // Logger 인스턴스를 unique_ptr로 관리
    unique_ptr<Logger> logger = make_unique<Logger>();

    // 다양한 로그 기록
    logger->logInfo("System is starting.");
    logger->logWarning("Low disk space.");
    logger->logError("Unable to connect to the server.");

    // 총 로그 개수 출력
    logger->showTotalLogs();

    // 아래 코드는 에러를 발생시킴 (unique_ptr은 복사할 수 없음)
    // unique_ptr<Logger> anotherLogger = logger;

    return 0;
}