목록C++ (58)
Coding Memo
문제 상황은 내 개인적인 상황에 해당한다. 엄청 복잡한 문제는 아니지만, 같은 문제를 발생시키는 일이 없도록 기록하려고 작성했다. (계속 추가...) ConnectEx - WSAEINVAL (10022) 에러 내용: ConnectEx를 호출할 소켓이 바인딩 되어 있지 않거나 수신 대기 중일 때 발생 문제 상황: ConnectEx 호출 시 발생한 에러 에러 이유: ConnectEx의 첫번째 인자인 소켓이 bind되어 있지 않은 소켓이어서 나타난 에러 해결: ::bind()를 통해 소켓에 로컬 주소와 포트를 바인딩 해준 후, ConnectEx함수를 호출했음 참고: https://learn.microsoft.com/ko-kr/windows/win32/api/mswsock/nc-mswsock-lpfn_conne..
에러 내용 ::WSAGetLastError()로 얻은값이 10022 (WSAEINVAL)값으로 에러가 발생했다. 나의 경우 ConnectEx함수 호출 후, 위 에러가 나타났다. 찾아보니 인수가 잘못되었다는 에러였는데, 도대체 여러개의 인자들 중 무엇이 잘못되었는지 몰라서 당황했다. (필요한 인자가 nullptr도 아니었고, 잘못된 인자가 없었다.) ConnectEx 문서를 보니 바로 이유를 알게 되었다... 해결 ConnectEx에 사용하는 소켓은 반드시 바인딩 되어 있어야 한다. ConnectEx 호출 이전에 소켓에 ::bind를 통해 나중에 연결에 사용될 로컬 주소와 포트를 바인딩해주면 된다. 추가적으로 소켓에 대한 유의 사항을 정리하면 소켓은 바인딩되어 있어야 한다. (주의할 점은 연결 할 엔드포인..

Error Create~~를 이용해 flatbuffer관련 객체나 구조체를 생성할 때 나타나는 에러이다. assert에 의한 에러이다. Problem 다음은 문제의 코드이다. CreateString을 이용해 flatbuffer 문자열을 만드는 중에 에러가 발생했다. #pragma comment(lib, "Release\\flatbuffers.lib") #include "flatbuffers/flatbuffers.h" #include "flatbuffers/util.h" #include "flatbuffers_scehmas/MyGame_generated.h" #include using namespace std; using namespace MyGame; int main() { // error codes {..
가상 소멸자 (virtual destructor)은 C++의 다형성과 관련된 기능 중 하나이다. 다음 코드에서와 같이 기본 클래스 (base class, parent class)에서 파생 클래스 (derived class, child class)의 포인터를 사용할 때, 파생 클래스의 소멸자를 호출하기 위해 가상 소멸자를 사용한다. class Base { }; class Derived : public Base { }; int main() { Base* ptr = new Derived(); // 파생 클래스의 포인터를 기본 클래스 포인터로 저장 /// ... return 0; } 위 코드에서 만약 delete ptr를 한다면 Base의 소멸자만 호출이 된다. 즉, Base에 대한 데이터는 delete 되지만..

C++ 컴파일러는 메모리에 구조체나 클래스를 배치할 때, 반드시 빈공간 없이 빽빽하게 메모리를 사용하지 않는다. 컴파일러는 CPU의 데이터 접근 효율성 향상을 위해 특정한 값으로 정렬을 하여 메모리에 데이터를 배치시킨다. (데이터 형식에 따른 일정한 간격 유지) (예를 들어, int 타입의 데이터는 빠른 메모리 접근을 위해 4배수의 메모리 주소에 저장할 것이다. 이로 인해 이전 메모리 공간에 빈 공간 (padding)이 생길 수 있다.) 만약 위 구조체에서 b가 int 타입이 아닌 double 타입이었다면 b를 8바이트 정렬하기 위해 a이후에 패딩을 추가할 것이다. | a(2) | padding(6) | b(8) | 즉, padding은 다음 순서에 오는 멤버의 데이터의 형식에 따라 존재여부와 사이즈가 ..

Use After Free는 해제된 메모리를 더 이상 사용하지 않아야 되는 상황에서 사용하려고 할 때 나타나는 매우 큰 문제이다. (Java나 C#같은 high-level 언어들은 이 문제에 신경을 덜 써도 된다.) Use After Free 문제는 다음과 같은 상황에서 일어날 수 있다. 메모리를 delete(free)한 후에 그 영역에 접근하려고 할 때 즉, 객체의 관점에서 본다면, 객체를 delete(free) 했지만 객체에 대한 포인터가 그대로 남아있어 그 포인터에 접근하려고 할 때 일어난다. 다음 코드를 살펴보고 문제가 되는 점을 찾아보자. using namespace std; class A { public: A() { cout
C++에는 값을 다음과 같이 분류할 수 있다. 정의 특징 gvalue generalized lvalue; 변수, 객체, 객체 멤버에 대한 모든 lvalue 표현식; lvalue와 xvalue가 여기에 모두 포함 prvalue pure rvalue; 일반적인 값으로 객체일 때 소멸자를 호출하지 않아도 되는 값; 어떤 연산자의 피연산자 값을 계산하거나 어떤 객체나 비트 필드를 초기화 할 때 계산되는 값 xvalue rvalue로 캐스팅 된 lvalue; 리소스를 재사용할 수 있는 개체나 비트 필드; 내부가 expiring 상태로 비어있음 (껍데기만 남아있음) - 내부 데이터가 만료되어 있는 상태일 수 있음 - 왼값을 move로 내부 데이터가 이동하면 xvalue가 됨 (캐스팅) lvalue 실체를 가지고 있..
로깅 라이브러리를 찾아보다가 한번 설치해보았다. 로깅을 위한 라이브러리로 C++14이상에서 작동한다. Google에서 만든 라이브러리로, 규모가 큰 프로젝트에 적합하다. 다른 라이브러리와 마찬가지로 로깅 레벨(INFO, WARNING, ERROR, FATAL)을 설정가능하다. 또한 조건부 로깅이 가능하다. (특정 조건에 의해서만 로깅을 할 수 있다. 매크로로 처리된다.) FATAL 로깅시에 해당을 로깅한 후에, 프로그램을 정지시키는 기능도 포함한다. 특징은 대용량 로그 처리가 가능하다는 것이라고 나와있다. 로그 파일을 자동을 분할하고 압축하는 기능을 제공하고 있다. 다만, 그만큼 조금 무거운 라이브러리이다. 설치 방법은 공식 문서에도 나와 있다. 사용해 볼 기회가 언젠가 있지 않을...까? 1. Gith..