[ 포인터 마무리 ]
배열과 포인터는 다르다
1차까지는 어떻게 호환? 되지만 ( 배열의 이름이 배열 처음을 가리키는 주소값이기 때문에)
2차는 완전히 다르다.
C++ 는 메모리를 프로그래머가 다룰 수 있는 위험한 언어.
강사 본인도 MMORPG 게임회사에서 근무할 당시 2시간에 한번씩 서버가 터졌는데
원인을 분석해보니 7년전에 누가 실수를 저질러 놨고 7년후에 누군가 그걸 밟은거였다.
이 처럼 메모리 문제를 한번 만나게 되면 로우레벨 문제가 사소한거 같지만 위험하고 중요하단걸 깨닭을 수 있다.
초보들이 가장 많이 하는 실수가 아래와 같은 부분이다.
#include <iostream>
using namespace std;
// 스택 프레임 [ 지역변수 ] a가 함수가 종료되면서 없어지는데 함수 반환을 지역변수 a의 주소값으로 하고 있다.
int* TestPtr() {
int a = 3;
return &a;
}
// TestWrong() 함수가 호출되면서 다시 한번 스택프레임이 쌓이는데 이때 그전에 사용되고 반납됐던, TestPtr() 스택프레임 부분이 재사용되게 되고,
// a[0] ~ a[99] 까지 100개의 int(4byte)가 스택프레임 [지역변수] 에 쌓이고 [매개변수]로 받은 ptr이 가리키는 값을 다시한번 0x12341234로 수정한다.
void TestWrong(int* ptr) {
int a[100] = {};
a[99] = 0xAAAAAAAA;
*ptr = 0x12341234;
}
int main() {
// TestPtr() 스택프레임의 지역변수 a의 주소를 리턴받고
int* ptr = TestPtr();
// TestPtr 호출이 종료되면서 스택프레임에 있는 a의 주소 값이 유효하지 않게 되는데, 엄밀히 말하면 메모리 입장에서는 사라지는게 아니고 스택프레임 관리 차원에서 esp를 땡겨주는것이기 때문에
// ptr에 담긴 값을 수정할 수 있다. ( 이 자체만으로도 치명적인 문제! 하지만 디버깅에 문제없이 작동된다. )
*ptr = 123;
TestWrong(ptr);
return 0;
}
이에 대한 내 질문은
답변 도 엄청 빠르게 답변해주신다.
'C++과 언리얼로 만드는 게임 개발 > Part1. C++ 문법' 카테고리의 다른 글
Day6 ( 52.67% ) (0) | 2022.03.30 |
---|---|
Day5 ( 47.32% ) (0) | 2022.03.28 |
Day3 ( 37.50% ) (0) | 2022.03.24 |
Day2 ( 29.46% ) (0) | 2022.03.24 |
Day1 ( 16.96% ) (0) | 2022.03.24 |