• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

10:11 코드 질문입니다.

23.03.29 22:18 작성 조회수 313

1

참조에 의한 값을 반환받는 함수를 이용해 역시 참조를 이용해 변수를 선언하면 함수가 끝나면서 사라지는 인자를 참조하므로 두번 출력하면 쓰레기값이 나온다고 설명해주셧는데요. Visual Studio 2019에서는 몇번을 출력해도 제대로 나오고 있습니다. 왜그런 건가요??

아래 코드 46~55줄 입니다.

 

#include <iostream>

#include <limits>

#include <array>

#include <vector>

#include <algorithm>

using namespace std;

//정수를 반환받는 경우

int getValue(int x) {

int value = x * 2;

return value;

}

int* getValue2(int x) {

int value = x * 3;

return &value;

}

int* allocateMemory(int size) {

return new int[size];

}

//reference로 반환

int& getValue3(int x) {

int value = x * 4;

return value;

}

int main() {

int value = getValue(3);

int value2 = *getValue2(3);

/*dereferencing해서 받는건 문제는 없으나 권장하지 않음

15~17의 value는 getValue2를 벗어나면서 사라지는데, 그 사라지는 변수의 주소값을 dereferencing하는건 위험

빌드해보면 값은 나오나 warning 뜸.

그렇다고 변수에 dereferencing은 더 위험. getValue2를 벗어나면서 사라지는 값의 주소값을 인자로 받는

값을 또 dereferencing 하는거니까

이 방법은 잘 안쓰긴 함. 단, 아래와 같이 배열의 동적할당에는 자주 씀. factory pattern이라고 나중에 배움.*/

int* array = allocateMemory(1024);

//int *array = new int[1024];와 동일

//대신, 동적 할당이므로 delete해줘야하는데 delete가 allocateMemory 함수 말고 main 함수에 있어야해서 단점임.

delete[] array;

int value3 = getValue3(5);//getValue3이 반환하는 레퍼런스가 가리키는 실제 값이 value3로 복사해 들어옴.

int& value4 = getValue3(5);

//이거는 문제. value4는 getValue3가 끝나면 사라지는 26번째 줄의 value를 참조함

//없어지는 변수의 값을 복사해서 가져오는 value3는 괜찮은데, 없어지는 변수를 직접 참조하는 value4는 문제겠지

//그 얘로 두번 출력해보면 한번은 제대로 나오는데 다음은 쓰레기값 나옴. 지워진 값의 주소를 참조하니까.

cout << value3 << endl;

cout << value3 << endl;

cout << value4 << endl;

cout << value4 << endl;

cout << value4 << endl;

return 0;

}

 

 

답변 1

답변을 작성해보세요.

2

Soobak님의 프로필

Soobak

2023.03.30

안녕하세요, 답변 도우미 Soobak 입니다. 🍉

질문자님의 아키텍처 환경은 x64 이고, 강의에서의 아키텍처 환경은 x86 이기 때문으로 생각됩니다.

한 번 x86 으로 아키텍처 환경을 변경하신 후, 프로그램을 실행해 보시면 강의와 동일한 결과를 확인하실 수 있으실 것으로 생각됩니다.

  • x86 환경에서 질문자님의 코드 실행 결과
    image

참고로, 이러한 차이가 발생하는 이유는 다음과 같습니다.

  1. 아키텍처마다 메모리를 관리하는 방식이 다르기 때문에, 동일한 코드여도 다른 결과가 출력될 수 있습니다.

  2. x86 아키텍처의 경우, 메모리 공간이 보다 더 제한적이기 때문에 메모리가 빠르게 정리되며, 함수가 종료된 후 반환된 참조값이 쓰레기 값을 가리키게 될 가능성이 더 높습니다.

  3. x64 아키텍처의 경우, 메모리 공간이 더 넓고 스택 관리 방식이 다르기 때문에, 함수가 종료된 후에도 반환된 참조값이 변경되지 않을 확률이 높아져서 정상적인 값이 출력될 수 있습니다.