본문 바로가기

C++

(56)
Placement new [1. 개요]placement new 라는 문법(혹은 기능) 은 일반적인 동적 할당 보다 조금 더 세밀하게 메모리의 수명을 관리할 수 있게 해준다. 일반적으로 객체를 대상으로 하는 new 는 메모리 할당 및 생성자 호출을delete 는 소멸자 호출 및 메모리 해제를 같이 진행 하게 해준다. 그러나, 아래와 같은 요구사항이 있을 수 있다.메모리를 할당만 하고, 생성자 호출은 뒤로 미루고 싶다.소멸자를 호출하여, 객체 내부의 메모리를 정리하지만, 객체 자체의 메모리는 당장 해제하지 않고 싶다.특히, 아래와 같은 상황도 있을 수 있다.공유 메모리를 대상으로 특정 객체를 공유하고 싶다.즉, 메모리는 이미 할당이 되어있지만, 객체의 생성자를 호출하고 싶다. 주의할 점은 소멸자가 자동으로 호출되지 않는다. (소멸자..
wchar_t 사용에 관하여 [2] [1. 개요]멀티바이트 문자열에서 wide char 문자열로 변환 혹은 그 반대 방향으로 변환 시 주의 점.Locale 에 대한 이해인코딩 변경이므로, 데이터 인코딩이 적절한지 확인출력에 관하여.[2. Locale 에 대한 이해]리눅스 기준으로는locale -a 를 이용하여, 현재 시스템에 설치된 locale 을 확인 할 수 있다.# locale-gen ko_KR.UTF-8 을 이용해서 한국어 관련 locale 을 설치 할 수 있다.윈도우에서 파워 쉘 기준으로는Get-WinSystemLocale 명령어로 확인 가능[3. 리눅스 관련 코드]#include #include #include #include #include int main(){ wchar_t wstr[128]; std:..
wchar_t 사용과 관련하여. [1. 개요]윈도우 환경에서 wchar_t 에 관련 된 여러 연산 들 중, 아래와 같은 연산 결과가 예상과 다름.iswdigitiswalphaiswalnum한글 '안' 을 유니코드로 표현하면, 10진수로 50504 이며,이는 기존 아스키 코드로 표현가능한 숫자, 영문이 아님을 알 수 있지만, 위 함수들의 결과는 숫자, 알파벳이라고 그 결과를 반환한다. 또, wstring 에 대해서, std::wcout 등을 통해 출력해도 정상적으로 문자열이 출력되지 않았음. 해결 방법을 알아보던 중, locale 을 제대로 설정하지 않았다는 것을 보았고, 그 밖에 관련된 것들이 아래와 같은데,std::locale() SetConsoleOutputCP(CP_UTF8);std::locale::global(std::local..
std::thread vs std::async
std::packaged_task [1. 개요]std::packaged_task는 C++11부터 도입된 기능으로, 함수나 함수 객체를 비동기적으로 실행시키고, 그 결과를 std::future를 통해 받아올 수 있도록 감싸주는 wrapper. 기본적으로 std::thread 로 실행 한 task 의 리턴 값을 받기 위한 별다른 메커니즘이 없다.std::promise 를 사용하는 것도 한가지 방법이기는 하지만,,,그러나, std::async 와 마찬가지로 task 의 리턴 값을 받기 위한 메커니즘을 제공한다는 측면이 있다.std::async 는 join() 을 따로 호출하지 않아도 되지만,std::thread 를 통해 호출하게 하므로, join() 의 호출은 필요 함.[2. 예제]가장 일반적인 사용 방법std::packaged_task 를 ..
std::bind [1. 개요]socket api 의 bind() 가 아니라, c++ 의 std::bind() 는 함수에 인자등을 미리 고정해서 함수 객체(callable) 를 만든다.아래와 같은 상황에서 주로 사용하는데,callback 을 등록 할 때,함수 객체 호출 시, 일부 인자를 미리 고정하고 싶을 때,다른 함수 객체들과 조합할 때,최신 C++ 에서는 lambda 식을 주로 사용하긴 하지만, 알아 둘 필요 있음.[2. 사용 방법 - 전역 함수]#include #include using namespace std;int add(int a, int b) { return a + b;}int main() { // add의 첫 번째 인자 10을 고정하고, 두 번째 인자는 나중에 받음 auto add10 = s..
bitfield 사용 시 유의할 점 [1. 개요]메모리를 bit 단위로 제어할 필요가 있을 때 사용하는 bitfield 에 대해서 사용 시 유의할 점.bitfield 멤버에 대해서 주소를 확인 할 수 없다. (주소연산 불가)비트 필드가 저장되는 순서 (MSB→LSB 등)는 플랫폼/컴파일러 의존적[2. 비트 필드가 저장되는 순서]Little-endian arch 에 g++ 컴파일러 기준으로 아래 예제를 실행하면,#include #include struct Mystruct { unsigned char a : 4; unsigned char b : 4;};int main(){ unsigned char c = 0x8f; Mystruct obj; memcpy(&obj, &c, sizeof(c)); std::cout 출..
std::stringstream [1. 개요] [2. 주의 사항]초기화 명목으로 보통 명명되는 clear() 함수는 stringstream 에서는 의도한 대로 작동하지 않는다.내부 버퍼를 초기화하는 역할로 동작하지 않음.stream 에서 clear() 함수는 보통, flag 등을 초기화하는 역할을 하기 때문...# failbit / eofbit 등.따라서, 내부 버퍼를 초기화 하려면, 아래와 같이 빈 문자열을 설정하도록 해야한다..str("");
OS 별 select() 함수 사용법 [1. 개요]select() 함수는 비동기 I/O 처리를 위한 시스템 콜이다.여러개의 파일 디스크립터(보통 소켓) 을 동시에 감시하면서, read/write/error 등의 상태를 체크한다. 함수 원형은 아래와 같다.int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); timeval 구조체의 내용을 채워, I/O 상태 변화를 timeout 동안 기다리고,NULL 이면, blocking 으로 동작하고,NULL 이 아니지만 0으로 채워져 있으면, non-blocking 으로 동작한다.[2. 주의점]위 함수 사용 시 주의할 점은 첫번째 파라미터이다.리눅스 커널에서는, readfds ,..
구조체 대입 연산 [1. 개요]구조체 간 대입 연산 시 생각 해 볼 만한 부분?별도로 복사 생성자나 대입 연산자 등을 구현하지 않으면, 컴파일러가 디폴트로 제공하는 것을 사용하게 되는데 멤버의 고정 길이를 갖는 배열이 있다면?Q) 얕은 복사가 발생하지 않나?A) 배열의 이름은 배열의 시작 주소를 포현하는 포인터이지만, 배열의 이름은 수정 할 수 없는 값이다. 따라서, 컴파일러는 고정 길이의 배열을 대상으로 깊은 복사를 하도록 디폴트 메소드를 제공한다. 어떻게 구현할지는 컴파일러 마다 다를 수 있음. (단, 배열은 그 크기를 아므로 memcpy 를 통해서 할 수 도 있다...)[2. 예제]#include #include struct Mystruct { int A; int B; ..