그린티라떼
개발공간
그린티라떼
전체 방문자
오늘
어제
  • 분류 전체보기 (26)
    • unity (6)
      • 개발 (4)
      • iTween (0)
      • error (2)
    • 게임서버 (5)
    • C++ (7)
      • 문법 (5)
      • 알고리즘 (2)
    • C# (5)
    • CS지식 (1)
    • 기타 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 컨테이너
  • 다중상속의 문제점
  • Container
  • 일반화
  • interface
  • 형식매개변수의 제약
  • C++
  • Dynamic
  • 일반화컬렉션
  • 유니티 빌드 에러
  • delegate chain
  • inline 함수
  • 함수호출
  • object
  • Functions
  • Gradle build failed
  • 제네릭
  • Delegate
  • var
  • 함수 호출 오버헤드
  • cout 스트림 버퍼
  • 메모리영역
  • 유니티
  • c#
  • 데이터타입
  • 정규 표현식
  • regex
  • property
  • unity
  • cs지식

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
그린티라떼

개발공간

C++/문법

(C++) 함수의 인자 또는 리턴 값에 STL 데이터 타입에 관하여

2022. 11. 12. 22:16

프로그래밍을 하다 보면 함수의 인자에 std::vector 등의 STL 데이터 타입을 넣는 경우가 있다.

이때 메모리 문제나 속도 문제에 대해서 생각해 필요가 있다.

 

값에 의한 호출 call by value

void func1(std::vector v) {...}

int main(){
	std::vector my_v {0,0,0};
	func1(my_v);
}

이 경우 v는 main()의 my_v를 넘기는 순간에 값을 복사하기 때문에 메모리가 증가하게 된다.

func1에서 v를 수정할 경우 main()의 my_v에 영향을 줄 수 없다.

 

만약에 main()에서 fun1()를 여러번 호출하게 된다면 매번 메모리가 사용될 것이다. 벡터는 상당히 큰 메모리 공간을 가질 수 있으므로 함수에 전달할 때 신중하게 고려해야 한다.

void func1(std::vector v) {...}

int main(){
	std::vector my_v {0,0,0};
    for(1~n){ func1(my_v); }
}

 

 

참조에 의한 호출 call by reference

void func2(std::vector& v) {...}
void func3(std::vector const& v) {...}

int main(){
	std::vector my_v {0,0,0};
	func2(my_v);
	func3(my_v);
}

main함수에서 func2()는 my_v를 넘기는 순간에 복사가 일어난다. 다만 복사되는 값이 my_v의 주소 값이다.

주소 값을 넘겼으므로 함수 func2()는 main()의 my_v에 영향을 줄 수 있다.

함수 func3()는 const 한정자를 사용하므로 읽기 전용이 된다.

 

 

함수에서 STL 데이터 받기

std::vector func4(){
	std::vector v {0,0,0};
    return v;
}

std::vector& func5(std::vector& v){
    return v;
}

int main(){
	std::vector my_v1 = func4();
	std::vector my_v2 = func5(my_v1); //my_v1과 my_v2는 별개의 변수
	std::vector& my_v3 = func5(my_v1);//참조자로 받았으므로 my_v1과 my_v3은 같음
}

my_v2는 일반 변수로 참조자를 반환받고 있어서 my_v1과 별개의 변수가 된다.

my_v3는 참조자로 참조자를 반환 받고 있어서 my_v1과 같은 메모리 위치에 있다.

 

my_v1는 v가 제대로 복사된다.

아래 코드와 같은 형태로 컴파일러가 데이터를 call by reference를 하여  func4()의 v 값들이 my_v1에 이동한다.

void func4(std::vector& v){
	v.push_back(0);
	v.push_back(0);    
	v.push_back(0);    
}

int main(){
	std::vector my_v1;
    func4(my_v1);
}

 

함수에서 참조자를 반환할 때 주의해야 할 점이 있다. 코드를 살펴보면

std::vector& func(){
	std::vector v={1,2,3};
    return v;
}

int main(){
	vector<int>& my_v = func();
}

func() 함수는  반환형이 참조자인데 지역 변수를 반환하고 있다. my_v는 지역변수은 v를 참조하고 싶은데 func() 함수가 끝나면서 메모리에서 지역변수 v가 소멸될 것이고 참조하지 못한 my_v는 오류가 날 것이다.

(v를 반환하는 부분에서 컴파일 경고가 발생한다.)

이렇게 해제된 메모리를 참조하는 참조자를 댕글링 레퍼런스(Dangling Reference)라고 한다. 

'C++ > 문법' 카테고리의 다른 글

c++ regex 정규 표현식  (0) 2021.12.22
if문 속 비교연산에서 순서의 비밀  (0) 2021.08.30
C++) Container비교  (0) 2021.08.25
C++) cout 스트림 버퍼/ 함수 호출 오버헤드/ Inline함수  (0) 2021.05.08
    'C++/문법' 카테고리의 다른 글
    • c++ regex 정규 표현식
    • if문 속 비교연산에서 순서의 비밀
    • C++) Container비교
    • C++) cout 스트림 버퍼/ 함수 호출 오버헤드/ Inline함수
    그린티라떼
    그린티라떼

    티스토리툴바