C++로 프로그래밍할 때 인자 또는 리턴 값으로 std::vector 등 STL 데이터 타입 처리하는 좋은 방법

C++ 프로그래밍할 때 std::vector 등 STL 데이터 타입을 호출하는 함수로 넘겨주거나 받아야 할 경우가 있다. 이런 경우 메모리 문제 또는 속도 문제 때문에 고민을 많이 할 것 같은데, C++11 이상을 지원하는 컴파일러를 사용하는 분이라면 이 글에서 도움을 받아 가기 바란다.

함수 인자로 넘길 때

이 경우는 사용이 명확하다. Call by Reference으로 데이터를 넘기면 된다. 
Call By Reference로 인자로 넘기는 방법은 pointer 를 사용해도 되지만, reference을 사용하는 것이 좋다.

void foo1(std::vector& data)
{
  ...
}

void foo2(std::vectorconst& data)
{
  ...
}

void foo3(std::vector data)
{
}

int main(int argc, char* argv[])
{
  std::vector my_data {10, 20, 30};

  foo1(my_data);
  foo2(my_data);
}

위 코드에서 foo1()과 foo2()는 Call by Reference로 값을 넘기는 반면에 foo3()는 Call by Value로 main()에서 my_data를 넘기게 된다. 


foo1()의 data는 main()의 my_data를 참조(reference)하고 있어서 foo1()에서의 데이터 변경은 main()의 my_data에 영향을 주게 된다.

그리고 foo2()는 main()의 my_data를 참조는 하지만 수정을 할 수가 없는 것이라서 단순히 값만 참조할 수 있게 된다.

반면 foo3()에서의 data는 main()의 my_data를 넘기는 순간에 값을 복사하기 때문에 메모리가 증가하게 된다. 또한 foo3()에서 data를 수정하더라도 my_data에 영향을 주지 않는다.


함수에서 데이터로 받기

이 과정에서 개발자들은 많은 고민을 하게 된다. 다음 코드를 보자.

std::vector foo()
{
  std::vector data { 10, 20, 30};

  return data;
}

int main(int argc, char* argv[])
{
  std::vector my_data = foo();
}

이런 경우에 과연 my_data에 값을 제대로 받을 수 있을까 생각할 수 있다.
결론은! 컴파일러가 데이터를 Call by Reference  형태로 foo()의 data의 값들이 my_data에 이동이 되어 효율적으로 전달이 된다.

그리고 C++11 이전 버전과 호환되는 방법은 다음과 같다.
void foo(std::vector& data)
{
  data.push_back(10);
  data.push_back(20);
  data.push_back(30);
}

int main(int argc, char* argv[])
{
  std::vector my_data;

 foo(my_data);
}

댓글

  1. 헉 안녕하세요 문득 궁금해서 찾아보다가 글을 발견하게 되었는데, 그럼 c++ 11 version은 함수를 call-by-reference로 작성할 필요가 없네요? void로 함수 input/output을 주고받으니 코드가 불명확해져서 불만이었는데 큰 깨달음을 얻었습니다...!!

    답글삭제
  2. 헉 안녕하세요 문득 궁금해서 찾아보다가 글을 발견하게 되었는데, 그럼 c++ 11 version은 함수를 call-by-reference로 작성할 필요가 없네요? void로 함수 input/output을 주고받으니 코드가 불명확해져서 불만이었는데 큰 깨달음을 얻었습니다...!!

    답글삭제
  3. 안녕하세요 김만수님
    저는 인공지능 스타트업에 다니는 정승환이라고 합니다.
    블로그의 내용들 정말 잘 보았습니다. 소중한 지식의 나눔, 감사드립니다.

    관련해서 간단하게 제안드릴 내용(온라인 강의)이 있어서
    메일로 연락드리고 싶습니다.
    정말 바쁘시겠지만,
    메일 한 번 이야기 나누어 볼 수 있을까요?

    제 메일은
    hwan@lionrocket.ai
    입니다. 회신주시면, 제안내용과 함께 꼭 설명드리고 싶습니다.

    좋은 하루 되세요 :)
    정승환 드림

    답글삭제

댓글 쓰기

이 블로그의 인기 게시물

macOS가 갑자기 부팅이 되지 않을 경우 데이터 복구 또는 백업 방법

Git 저장소를 병합하는 방법(How to merge repositories in Git)