개발/C·C++
-
[윈도우 시스템 프로그래밍] 압축 파일 복사하기개발/C·C++ 2024. 8. 27. 23:17
파일을 윈도우에서 제공하는 API를 통해 메모리로 추상화를 하면 파일을 메모리처럼 사용할 수 있다. 텍스트 파일을 메모리로 추상화하면 strcpy_s() 함수를 이용해 텍스트 파일에 문자열을 복사할 수 있으며 같은 맥락에서 파일 복사 역시 memcpy_s() 사용해서 편하게 복사할 수 있다. 기본 과정은 어렵지 않고 세부적으로 함수를 호출할 때 플래그만 잘 넣어주면 된다. 예를 들어 읽기 속성으로 파일 핸들을 구했는데, 매핑 객체를 만드는 함수를 호출할 때 읽기/쓰기 플래그를 넣으면 정상적인 반환 값을 얻을 수 없다. 테스트 파일은 압축 파일이다. 압축 파일은 crc로 무결성을 검사하기 때문에 정확한 복사 여부를 확인할 수 있기 때문이다. 복사한 압축 파일을 풀어서 데이터를 열람할 수 있으면 된다. 다음..
-
std::remove_if, std::erase개발/C·C++ 2024. 8. 17. 20:18
이 둘을 이용해서 데이터를 지우는 로직은 보통 다음과 같다.auto it = std::remove_if(data_vector_.begin(), data_vector_.end(), [remove_node](const std::unique_ptr>& node) { return node.get() == remove_node; }); if (it != data_vector_.end()) { data_vector_.erase(it, data_vector_.end());} remove_if의 구현 방식은 대단히 간단한데 다음과 같다.(참고링크)templateForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPred p){ fir..
-
전화번호 무작위 생성개발/C·C++ 2024. 8. 3. 13:57
테스트 삼아 10,000개의 데이터를 선형 자료구조에서 중복 검사까지 하면서 생성해보니 6~7분 정도 걸리는 것 같다. C++에서 제공하는 라이브러리들은 비선형 구조이기 때문에 데이터 삽입과 탐색이 선형 자료구조에 비해 압도적으로 빠르다. PhoneNumberMaker 클래스에서는 PhoneNumberMakerImpl의 unique_pointer만 들고 있고 실제 구현은 PhoneNumberMakerImpl에서 이뤄진다. 이 구조의 장점은 데이터를 가리키는 포인터와 실제 데이터를 클래스로 구분할 수 있다는 점이다. 별도의 클래스 생성으로 아주 약간 메모리를 더 쓰긴 하지만 차이는 미미하다고 봐도 될 것 같다. PhoneNumberMaker은 일종의 인터페이스만 제공하는 역할을 한다 PhoneNumber..
-
[정렬] 더미 노드와 병합 정렬개발/C·C++ 2024. 7. 18. 14:02
연결 리스트를 정렬하는 데에는 병합 정렬이 최적이다. 시간 복잡도가 평균적으로 N(log(2)N)을 보장하며 순서가 뒤바뀌지 않는 안전 정렬이다. 구현한 연결 리스트는 더미 헤드 노드와 더미 테일 노드를 가지는데 이 존재가 정렬할 때 조금 문제가 되었다. 나이와 전화번호를 가지고 있는데, 정렬의 포인터는 헤드 노드 포인터의 next_ptr부터 시작할 수 있으므로 문제가 되지 않지만 더미 테일 노드는 제외하는 로직을 넣어야 하기 때문이다. 병합하는 과정에서, 마지막 과정임을 확인하는 건 작업하는 노드의 갯수를 세는 방법밖에 없으므로 카운팅 로직 하나당 O(N)의 시간 복잡도가 발생하는데, 총 세 번이 발생한다. 데이터의 양이 적을 땐 유의미하지 않지만 데이터가 200만개가 되니까 처리 시간이 급속도로 늦어..
-
[디스어셈블리 코드] 간단한 메서드 호출과 동작을 해석해보자개발/C·C++ 2024. 7. 13. 13:52
다음과 같은 코드가 있다.#include class MyData {public: void setData(int data) { this->data = data; } private: int data = 0;};int main() { MyData a; a.setData(10);} setData 메서드 호출 직전에 디스어셈블리 코드에서는 다음과 같은 작업을 확인할 수 있다 MyData a;00007FF605341A2D lea rcx,[a] 00007FF605341A31 call MyData::MyData (07FF60534120Dh) a.setData(10);00007FF605341A36 mov edx,0Ah 00007FF605341A3B lea ..
-
메모리 정렬, 패딩 그리고 비트필드(feat. 구조체)개발/C·C++ 2024. 7. 7. 10:37
컴퓨터는 극한의 효율을 추구해야 한다. 경쟁에서 우위를 점해야 하기도 하고 엔지니어 관점에도 같은 전기를 쓰면서 최대 성능과 최대 효율을 뽑는 것이 중요한 문제일 수밖에 없다. 메모리 정렬에 몇 가지 규칙이 존재한다.1. 데이터가 저장되는 메모리 경계가 존재한다2. 1 바이트 데이터는 1 바이트 경계, 4 바이트 데이터는 4 바이트 경계3. 여기서 말하는 경계는 4바이트 데이터가 저장되는 시작 주소가 4의 배수인 것을 말한다4. 예를 들어 배열이 아닌 int형 데이터는 0x00000040(편의상 32비트 주소 체계 기준)에 저장된다 메모리 정렬을 이야기할 때 데이터를 모아놓은 구조체가 자주 등장한다.다음의 두 구조체는 자료형의 총합은 같지만 실제 메모리 공간에서 차지하는 크기가 다르다.// 정렬되지 않은..
-
문자열 파싱 연습하기(feat. strtok_s)개발/C·C++ 2024. 7. 4. 16:39
C 표준 함수인 strtok_s는 원본 배열에 건드리기 때문에 const char*을 인수로 받지 않는다. 구분자는 하나의 문자열에 넣어주면 되고 내부 상태값을 유지하기 위해 외부에서 선언한 포인터 변수의 주소를 전달하면 된다. 여기서 말하는 내부 상태 값은 원본 문자열을 검색할 때 다음의 시작 주소다. strtok_s과 동일한 로직을 가지고 사용법도 동일한 MyStrTok을 구현해보자. #include char* MyStrTok(char* string, const char* delimeter, char** context);bool IsDelimiter(char ch, const char* delimiter);int main() { char buffer_string[64] = { "data = x + y..