Study/에러 정리

중단점 명령(__debugbreak() 문 또는 유사한 호출)이 에서 실행되었습니다.

Juzdalua 2024. 9. 2. 18:22

_free_dbg
메모리 해제를 두번 시도하여 발생하는 에러.


Protobuf 클래스 내부에 클래스를 포함하려다 문제가 발생했다.

{
    Protocol::ErrorObj errorPkt;
    errorPkt.set_errorcode(-1004);
    errorPkt.set_errormsg("ID not exists");

    Protocol::S_LOGIN pkt;
    pkt.set_success(false);
    pkt.set_allocated_player(nullptr);
    pkt.set_allocated_error(&errorPkt); // Error
    uint16 packetId = PKT_S_LOGIN;
    SendProtobuf(pkt, packetId, session);
}

1. 스택에 할당된 errorPkt 객체는 스코프가 종료되면 메모리에서 해제된다.

2. pkt가 해제될 때, 할당된 errorPkt를 다시 메모리에서 해제하는데 이미 해제된 메모리이기 때문에 에러가 발생한다.

set_allocated_error 함수는 errorPkt 포인터를 Protocol::S_LOGIN 메시지의 error 필드에 할당합니다.
이 함수는 기본적으로 할당된 포인터의 소유권을 S_LOGIN 메시지에 넘기고, 메시지가 소멸될 때 포인터가 가리키는 메모리가 해제됩니다.

 

수정코드

 

// proto
message S_LOGIN
{
	bool success = 1;
	Player player = 2;
	ErrorObj error = 3;
}

// cpp
unique_ptr<Account> account = AccountController::GetAccountByName(recvAccount.name());
if (account == nullptr) {
	cout << "ID not exists";

	auto errorPkt = new Protocol::ErrorObj();
	errorPkt->set_errorcode(-1004);
	errorPkt->set_errormsg("ID not exists");

	Protocol::S_LOGIN pkt;
	pkt.set_success(false);
	pkt.set_allocated_player(nullptr);
	pkt.set_allocated_error(errorPkt); // 소유권을 protobuf에 넘긴다 -> 메모리 해제를 자동으로 함.
	uint16 packetId = PKT_S_LOGIN;
	SendProtobuf(pkt, packetId, session);

	return false;
}