-
람다의 참조 캡처는 종종 불안하다
앞서, 콜백 함수의 인자는 C++17의 apply와 tuple을 이용해 처리할 수 있지만 예제를 최대한 간소화하기 위해 콜백 함수의 인자는 하나로 설정했다. 같은 이유로 요청을 처리할 함수는 멤버 함수가 아니라 전역 함수를 사용했다. 커맨드 패턴을 활용해 요청을 Job 객체로 만들어 큐에 넣고 공통 api-보통 커맨드 패턴에서는 Execute()를 애용하므로- Excute()를 호출해 Job(이하 일감)을 처리한다.일감을 실행하기 위한 callback 함수를 요청 객체에서 가지고 있다가 Execute()를 할 때 callback() 함수를 호출하는 구조를 단순홰해서 볼 건데 callback은 람다로 구현할 것이다. 이 때 람다 본문에서 필요한 변수들은 참조 객체를 해도 될까? 값 복사는 비용이 들고 참조..
-
[Protobuf 따라하기] 수신 데이터를 복사 없이 가공하기
고정 패킷 이후에 등장하는 가변 데이터는 많고 이를 vector로 관리하게 되면 어쩔 수 없이 복사 비용이 발생한다. 개발이 비교적 편한 건 장점이지만 성능 면에서는 단점이다. 이 단점을 개선하기 위해 포인터를 활용하면 유지보수성이나 가독성이 조금 떨어질 수 있지만 성능에서는 이점이 있으므로 트레이드-오프를 잘 생각해자. 고정 패킷을 읽는 건 쉽다. 그냥 형 변환을 하면 된다.// 패킷#pragma pack(push, 1)struct PacketTest{ struct BuffListItem { uint64 buff_id; float remain_time; }; uint16 packet_size; // 공용 헤더 uint16 packet_id; // 공용 헤더 uint64 id; uint32 hp; u..
-
VirtualAlloc()의 메모리 할당에 대해
VirtualAlloc()이 과거에는(?) 메모리 할당이 64KB 단위로 이루어졌던 것 같다.과거의 데이터로 학습한 Perplexity의 대답도 그렇고윈도우 시스템 프로그래밍 관련한 강의(최근에 제작된 것)에서도 관련한 내용으로 학습했다. 개인적으로 정리를 하던 와중에 정말 VirtualAlloc()으로 메모리 요청을 했을 때정말 최소 할당 값이 64KB이 궁금했고 테스트를 해봤다.현대적인 윈도우는 메모리 풀링을 하지 않고 new / delete만 써도 메모리 최적화가 잘 된다는 실무자 전언을 들었다.메모리 풀링을 하는 몇 가지 이유는 작은 메모리 공간을 요청에 대한 오버헤드가 큰 것과 작은 메모리 공간에 대한 잦은 할당과 반복이 메모리 단편화를 만들 수 있기 때문이다. 이 이야기를 들어서일까 Virtu..
-
64비트 시스템에서 메모리 정렬 경계에 대해
64bit 프로세서의 64bit 모드에서 메모리 동적할당을 하면 주소 값이 16바이트 정렬이 기본 값인 것 같다.struct PureNode{ int a; int b; int c;};int main(){ constexpr int ALIGN = 16; for (int i = 0; i (new PureNode()); uintptr_t node2 = reinterpret_cast(new PureNode()); uintptr_t node3 = reinterpret_cast(new PureNode()); uintptr_t node4 = reinterpret_cast(new PureNode()); uintptr_t node5 = reinterpret_cast(new PureNode()); ASSERT_C..
-
포인터 붕괴와 붕괴가 아닌 것
int형 2차원 배열을 선언한다.int buf[100][100]; 다음 둘의 주소 값이 같을까?cout 정답. O.2차원 배열의 첫 번째 행의 시작 주소를 가리킨다.auto를 이용해서 타입 확인을 해보면 타입이 다르다. 주소값은 같은데 타입이 다르다?무슨 의미일까. buf[0]은 사실상 int[100]의 시작 주소이므로 int* 타입으로 붕괴된다.문제는(?) &buf[0]인데, 이 표현식은 행 전체를 &으로 묶는 효과가 생긴다.타입은 (int*)[100]이 된다. 100개의 정수 배열에 대한 포인터다.조금 풀어서 이야기 하보면, buf[0]이 1차원 배열의 시작 주소를 가리키는데 이 앞에 주소 연산을 붙이니 1차원 배열 단위의 주소 연산을 할 수 있게 된다는 거다.코드로 확인해보자.auto p1 = ..