포인터
-
[Protobuf 따라하기] 수신 데이터를 복사 없이 가공하기개발/C·C++ 2024. 11. 8. 17:28
고정 패킷 이후에 등장하는 가변 데이터는 많고 이를 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..
-
포인터의 타입 추론개발/C·C++ 2024. 8. 31. 12:31
templatevoid f(T* param){ cout f() 함수는 T*으로 인수를 받고 있다. const int*로 선언된 pcx 변수를 전달하면 어떤 타입으로 추론이 되는지 살펴본다. 답을 보기 전에 가능한 시나리오를 검토해보자.pcx는 const int*이니까 T는 const int가 될 수도 있고 모종의 이유로 const가 탈락한 int가 될 수도 있다. 혹은 T* 이므로 해당 타입이 가리키는 타입으로 추론될 수도 있을 것이다. 정답은 아래를 드래그 하면 된다. int 예상 가능한 시나리오의 세 번째에 해당한다고 볼 수 있다.T*은 해당 포인터 변수가 가리키는 타입을 추론한다. int형 가리키기 때문에 int로 추론된다.그렇다면 f() 함수의 파라미터가 T이면 어떨까?#include #in..
-
[정렬] 더미 노드와 병합 정렬개발/C·C++ 2024. 7. 18. 14:02
연결 리스트를 정렬하는 데에는 병합 정렬이 최적이다. 시간 복잡도가 평균적으로 N(log(2)N)을 보장하며 순서가 뒤바뀌지 않는 안전 정렬이다. 구현한 연결 리스트는 더미 헤드 노드와 더미 테일 노드를 가지는데 이 존재가 정렬할 때 조금 문제가 되었다. 나이와 전화번호를 가지고 있는데, 정렬의 포인터는 헤드 노드 포인터의 next_ptr부터 시작할 수 있으므로 문제가 되지 않지만 더미 테일 노드는 제외하는 로직을 넣어야 하기 때문이다. 병합하는 과정에서, 마지막 과정임을 확인하는 건 작업하는 노드의 갯수를 세는 방법밖에 없으므로 카운팅 로직 하나당 O(N)의 시간 복잡도가 발생하는데, 총 세 번이 발생한다. 데이터의 양이 적을 땐 유의미하지 않지만 데이터가 200만개가 되니까 처리 시간이 급속도로 늦어..
-
문자열 파싱 연습하기(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..
-
[Pointer] 달과 손가락개발/C·C++ 2021. 4. 10. 17:44
포인터는 주소값을 담는 변수 그 이상 그 이하도 아닙니다. 포인터가 어려운 이유는 주소를 다루는 점 때문에 그렇습니다. 이 모든 건 주소 때문입니다. 개발자가 주소를 직접 다룰 수 있는 언어는, 지금 활발하게 사용되는 언어 중에서는 C/C++가 대표적입니다. typeid를 이용해 타입을 출력해보면 pNum의 공식적인 타입을 확인할 수 있습니다. #include using namespace std; int main() { int num0 = 0; int* pNum = &num0; cout
-
참조변수에 대한 작은 오해개발/자바 2020. 3. 16. 14:33
자바에서 기본 자료형 변수를 만들 때를 제외하고, 객체는 전부 new 연산자를 이용해 동적으로 메모리를 할당한다. new 연산자가 반환하는 것은 내부적으로는 메모리의 주소겠지만 자바에서 개발자는 메모리 주소를 알 수 없고 해싱을 거친 참조값(해시코드)만 확인할 수 있다. 애초에 자바에서는 메모리를 직접 다룰 일이 없다. 참조값은 메모리 주소 정보를 갖고 있기 때문에 C/C++의 포인터와 같다고 봐도 된다. 객체를 매개변수로 넘길 때 해당 객체의 참조값이 전달되므로 함수 내에서 객체의 데이터를 변경하면 외부에서도 바뀐 결과를 확인할 수 있다. 다음의 결과는 Lee가 출력된다. changeName()의 매개변수 student는 지역변수이지만 main()에서 생성한 Student 객체의 참조값을 가지고 있으며..