와이드용 애드센스


[C++] return by reference의 특징과 사용 시 주의점 C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
 
using namespace std;
 
struct job {
    char jname[20];
    int role;
    double pay;
};
 
const job & findJob(job &j);
 
int main()
{
    job j1 = { "DB Design"1100.33 };
    job j2;
    j2 = findJob(j1);
    cout << j2.role;
    return 0;
}
 
const job & findJob(job &j)
{
    j.role = 2;
    j.pay += 200.234;
    return j;
}
cs

C++ 에서 함수 처리 return 메커니즘은 return 값을 임시 저장 공간에 복사한 후 그것을 return하는 방식이다.

하지만 return by reference 형식을 사용할 경우 임시 저장공간을 사용하지 않고 호출 함수가 return값에 직접 접근을 하게 된다.

예제의 경우 reference에 의한 return이기 때문에 findJob 함수는 임시변수에 저장된 값이 아닌 j1의 reference를 리턴하며, main()함수에서 j2.role은 j1.role의 값을 복사하게 되는 것이다.



그러나 Return by reference 형식을 사용할 때에는 반드시 주의해야할 점이 있다.

아래의 코드를 실행해 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "pch.h"
#include < iostream >
 
using namespace std;
 
int& f1()
{
    int a = 30;
    return a;
}
 
int& f2()
{
    int b = 40;
    return b;
}
 
int main()
{
    int &refer1 = f1();
    int &refer2 = f2();
 
    cout << refer1 << endl;
}
cs

[그림 1] 코드 실행 결과


f1() 함수의 리턴 값은 30으로 refer1에 저장되었는데, f2()까지 실행 후 refer1을 출력해보니 기대했던 값인 30이 아니라 엉뚱하게도 40이 나오고 있다. 왜 이런 논리적 오류가 발생하는 것일까?

[그림 2] 코드 실행시 메모리 구조 가정


이유는 바로 함수 내의 로컬 변수의 reference를 참조할 경우, local 변수는 함수 종료시 파괴되지만 refer1의 경우reference 자체를 계속해서 참조하고 있기 때문이다.

[그림 2]를 보면 f1()의 실행이 끝난 후 f2() 호출될 때 로컬 변수(int b)를 사용하기 위해 해당 주소에 또다시 할당을 받아버렸고, &refer1은 여전히 같은 주소를 가리키고 있기 때문에 int b=40; 코드가 실행되는 시점에서 refer1의 값 또한 40이 되어버린 것이다.

예제에서는 f1()이 호출된 후 바로 f2()가 호출되어 같은 자리에 값이 할당되었지만, 경우에 따라 다른 값 혹은 쓰레기값이 들어올 경우도 있기 때문에 refer1의 값은 오류가 발생할 수도 있는 값이라는 문제점을 가지고 있는 것이다.

return by reference 형식을 사용할 경우 컴파일에는 성공할 지 몰라도 이러한 논리적인 오류가 발생할 가능성이 높기 때문에 code를 작성할 때 주의가 필요하다.

 

덧글

  • yundorri 2021/12/09 14:41 # 삭제 답글

    글 잘읽었습니다.
    하지만, 애초에 로컬변수는 함수가 종료됨과 동시에 파괴되는걸 알고 있다면 파괴될 변수를 참조하여 반환하는것 부터가 잘못사용한 것 아닐까요? ^^
댓글 입력 영역



애드센스