배열 쉬프트 관련 질문입니다.
글쓴이: 익명 사용자 / 작성시간: 금, 2022/06/17 - 9:45오전
i번째 클라이언트가 나가면 i번째 배열값을 없애고 그 뒤의 값들을 앞쪽으로 당겨오는걸 해보고 있는데
나가는 순서가 바뀔때마다 중간에 공백이 하나 생기네요
어떤식으로 바꿔야하나요..?
for (int i = 0; i < client_list.size(); i++) { if (client_list[i] == socket) { //user_ip = m_user_list[i].Ip_Address; //AfxMessageBox(user_ip); DisConnectInfo_str.Format("IP : %s 가 종료했습니다. \n", m_user_list[i].Ip_Address); DisConnectInfo_str2.Format("IP : %s\n", m_user_list[i].Ip_Address); //DisConnectInfo_str.Format("접속 종료 IP : %s, Port : %d\n", inet_ntoa(dlg->FromClient.sin_addr), dlg->client_addr.sin_port); dlg->m_ListChat.AddString(DisConnectInfo_str); dlg->m_ListClient.DeleteString(dlg->m_ListClient.FindString(-1, DisConnectInfo_str2)); for (int j = 0; j < client_list.size(); j++) { if (client_list[j] == socket) { strcpy(m_user_list[j].Ip_Address, ""); } m_user_list[j] = m_user_list[j + 1]; strcpy(m_user_list[j + 1].Ip_Address, ""); } } }
Forums:
i번째걸 지워야해서
i번째걸 지우고 당겨야해서
이렇게도 바꿔보고
이렇게도 해봤는데 이건 순서대로는 나가지는데 중간에 들어온거부터 나가면 벡터에 있는 소켓까지 그냥 다 날려버리네요...
이렇게 하면 사이드 이펙트 생길겁니다.
client_list 를 이용해서 반복문을 실행하는 루프안에
client_list 를 다시 수정하는건 해서는 안되는 행위입니다.
차라리 해당 인덱스 부터 뒤에거를 앞으로 복사하고(end -1 일땐 제외) 루프 밖에서 마지막껄 지우시는걸 추천합니다.
------------------------------------------------------------
ProgrammingHolic
수정하겠습니다
말씀해주신거 참고해서 변경해보겠습니다.
아래 사항을 점검해 보시기 바랍니다.
아래 사항을 점검해 보시기 바랍니다.
1. list, vector, map 같은 STL 중에서 왜 vector를 사용해야 하는가? 구현하려는 기능에 vector가 가장 최적화되어 있는 STL 객체인가?
2. vector 객체를 쓰면서 왜 client_list 와 같은 혼동을 줄 수 있는 이름을 사용해야 하는가?
3. for() 문에서 i와 iter를 별도로 사용해야할 필요성은 무엇인가?
4. 구현시 웹에서 찾을 수 있는 예제로부터 시작해 보았는가?
검토해보겠습니다
말씀해주신 부분 검토해보겠습니다 감사합니다
1. vector를 쓰는 건 뭐 좋습니다.
1.
vector
를 쓰는 건 뭐 좋습니다.vector
는 원래 시퀀스의 한가운데에서 삽입/삭제가 자주 이루어지는 상황에 적절한 컨테이너는 아니긴 합니다.하지만 뭐, 주어진 상황에서 client_list는 접속한 클라이언트 숫자만큼의 크기를 가질 텐데, 커 봐야 얼마나 크겠어요?
클라이언트가 접속 끊고 나가는 상황은 또 얼마나 자주 있겠습니까.
2. i에 대해 돌아가는 루프 안에 j에 돌아가는 루프가 있는 게 이상하지 않아요?
로직을 잘 고민해보면 이게 애초에 이중 루프를 쓸 문제가 아니라는 점을 깨닫게 될 겁니다.
3. C++를 쓴다면 C++에 맞게.
m_user_list[i].Ip_Address
에strcpy
를 쓰시는 걸 보니 C-style 문자열인 듯 한데, 그런 거 C++에서 사용하는 건 웬만하면 지양하세요.std::string
이든CString
이든 (MFC 맞죠?) 쓰는 게 편합니다.4. STL를 쓴다면 STL에 맞게.
STL 시퀀스 컨테이너에서 원소를 삭제할 때는 Erase–remove idiom이 주로 쓰였습니다.
https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom
위키피디아 항목을 보고 오셨다면 아시겠지만, C++20부터는 그냥
std::erase
쓰셔도 됩니다.https://en.cppreference.com/w/cpp/container/vector/erase2
세상 참 좋아졌어요. 그렇지 않습니까?
감사합니다
2번에 대해선 좀 공부를 해봐야겠네요 나머지 충고도 정말 감사합니다
킹코틀린 쓰세요
킹코틀린 쓰세요
댓글 달기