Programming/C++ & Unreal

Programming/C++ & Unreal

C++ 람다에서 클래스 멤버 변수를 복사로 캡쳐하여 사용하면 클래스 자체를 복사한다.

개요C++에서 람다로 복사 캡쳐 하여 클래스의 멤버 변수를 사용하면 멤버 변수만 복사되어 넘어오는 것이 아니고, 클래스 그 자체가 복사된다.C#에서는 async의 매직 코드로 멤버 변수만 넘어왔었는데, 이 사실을 모르고 C++에서도 비슷하게 사용했다가 복사로 인한 부하가 심각하게 발생하는 문제가 발생하였었다. -_-;; 코드#include class CMember{public: CMember() { std::cout void { MyFunction(main_class); }; return 0;}/*CMember 기본 생성자CMain 기본 생성자**** 람다 생성 ****CMember 기본 생성자CMain 복사 생성자*/자 이렇게 main_class를 복사 캡쳐 모드에서 사용하면 main_cl..

Programming/C++ & Unreal

메모리 파편화 + boost, tbb 도구

개요C++ 틱 베이스의 게임 서버에서 std::vector나 std::map을 매 초마다 수만, 수십만 회 생성하고 있는데 N시간이 지나면 이 코드에서 메모리 파편화(추정)가 심해져서 heap 할당 시에 CPU 사용량은 낮아지고 모든 스레드가 직렬화되는 문제가 확인되었다. 위 문제를 해결하기 위해서 pooling, 할당자 관련 도구를 찾다가 간단하게 정리해 보려고 포스팅하였다. 도구 한 줄 정리boost object pool : 매우 큰 오브젝트 하나하나를 직접 다루기 좋은 도구.boost pool_allocator : boost object pool 기반으로 할당해 주는 기능.boost fast_pool_allocator : boost object pool 기반으로 할당해 주는 기능. 단일 스레드 앱에..

Programming/C++ & Unreal

C++ 스마트 포인터 메모리는 shared_ptr가 없어져도 해제되지 않는다.

개요C++ 스마트 포인터 shared_ptr의 참조 카운트가 0이 되어도 weak_ptr이 참조하고 있다면 메모리를 해제하지 않고 소멸자만 부른다. 스마트 포인터 간단 요약 스마트 포인터의 기본 원리는make_shared시에, control block(스마트 포인터 관리용 오브젝트)와 object(실제 사용하는 오브젝트)가 생성된다.이후 shared_ptr이 참조할 때마다 use_count가 늘어나고,weak_ptr이 참조할 때 마다 weak_count가 늘어난다.use_count가 0이 되면 object의 소멸자가 호출되고,모든 count가 0이 되면 control block과 object의 메모리가 해제된다. 메모리 해제 시점상식적으로 use_count가 0이 될 때, object의 메모리를 해제해야..

Programming/C++ & Unreal

vprintf, vsprintf 등 가변 인자 함수를 활용한 로그 함수 개발 시에 포맷 warning 출력하기

printf C++에서 printf 사용시에 format을 잘못 지정하였다면 이렇게 컴파일러단에서 C4477 C4313 C6067 의 워링 에러가 발생하여 잘못된 포맷으로 인한 오류나 크래시를 방지 할 수 있다. vprintf, vsprintf... 하지만 보통 printf를 저렇게 사용하는 일은 거의 없다. 아래와 같이 보통 로그를 남기는 함수를 va_list를 사용하여 커스터마이징하곤 한다. (UE_LOG도..) 하지만 이렇게 사용하면 포맷 관련 warning이 발생하지 않아서 실수를 저지르기가 너무 쉽다. 해결법 MSVS에서는 저런 사용자 함수에서 포맷 체크를 하는 방법이 없어서 이렇게 편법으로 Debug 빌드 시에만 printf로 체크하는 방식이 가능하다. sizeof() 안에 있는 printf구..

Programming/C++ & Unreal

StackWalk64가 context에 의하여 Access violation를 유발

#include #include #include BOOL InitSymHandler(HANDLE hProcess) { if (SymInitialize(hProcess, NULL, TRUE)) { SymSetOptions(SYMOPT_LOAD_LINES); return TRUE; } return FALSE; } LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exceptionInfo) { CONTEXT* context = exceptionInfo->ContextRecord; STACKFRAME64 stackFrame; memset(&stackFrame, 0, sizeof(STACKFRAME64)); stackFrame.AddrPC.Mode = Addr..

Programming/C++ & Unreal

C++ 가변인자(va_list)를 오버로딩 하지 말자.

#include #include void Print(const char* format, va_list args) { // 2번째 Print 함수에서 호출함 vprintf(format, args); } void Print(const char* format, ...) { // main 에서 호출함 va_list args; va_start(args, format); Print(format, args); va_end(args); } int main() { char a[] = "Hello "; char b[] = "world!"; Print("%s %s", a, b); // "Hello world!" 출력됨. return 0; } 위 코드는 아무 문제가 없다. 가변인자가 잘 들어가서 2번째 Print 함수 -> ..

Programming/C++ & Unreal

C++ parallel for_each (thread) exception

#include #include #include #include #include #include LONG WINAPI UnhandleExceptionHandler(_EXCEPTION_POINTERS* exceptionInfo) { std::cout

Programming/C++ & Unreal

C++ RTTI 구현

개요 RTTI는 Run Time Type Information의 약자로 프로그램이 실행된 시점에 Type을 알 수 있는 기능이다. 기본 #include using namespace std; class A { }; class B { }; int main() { A a; B b; cout

Programming/C++ & Unreal

Xcode tbb 설치

1. 터미널 실행 2. 터미널로 tbb 설치 brew install tbb 3. Xcode 프로젝트 파일 클릭 4. Build Settings에 Include, Lib Path 지정 5. Build Phases에 라이브러리 파일 링크 추가 끝 boost 설치도 거의 비슷한데, brew 말고 macPort 라는 것을 통해서 받았음.

Programming/C++ & Unreal

C++ 오브젝트풀 개선 with tbb

#pragma once #include #include #include template class CObjectPool{ public: CObjectPool(int size = 100){ _maxSize = size; for (int i = 0; i < _maxSize; ++i) { T* newObject = new T(); _qObjects.push(newObject); } } ~CObjectPool() { while (!_qObjects.empty()) { T* object; if( _qObjects.try_pop( object ) == true ){ delete object; } } _maxSize = 0; } // 오브젝트를 꺼낸다. T* PopObject() { T* retVal; // 꺼낼게 ..

장형이
'Programming/C++ & Unreal' 카테고리의 글 목록