Memory & Pointer

EHminShoov2J·2023년 8월 17일
0

CPP/코딩테스트

목록 보기
4/25
post-thumbnail

1. 메모리

메모리는 프로그램 실행중에 데이터가 저장되는 시스템 공간이며, 각각의 메모리는 고유한 주소를 가지게 된다.

1.1. & 연산자

& 연산자는 일반 변수(pointer 변수가 아닌)와 같이 사용되는 경우, 해당 변수의 주소를 리턴한다.

#include <iostream>

using namespace std;

int main(){
    cout << "Memory & Pointer" << endl;

    int i = 10;
    cout << &i << endl ; // &는 일반변수 앞에서 사용될 때 일반변수의 주소를 리턴! 
    // 값이 변한다고 해서 변하지 않음

}

2. 포인터

포인터란 다른 변수의 메모리 주소를 저장하는 변수를 의미한다.

2.1. *(에스터리스크)연산자

(타입) *(변수명) 다음과 같이 pointer 변수를 선언할 수 있다.
또한 pointer 변수 앞에서 쓰이는 경우 역참조 연산자가 되어, pointer 변수가 가르키고 있는 주소의 메모리에 담긴 값을 리턴한다.

#include <iostream>

using namespace std;

int main(){
    cout << "Memory & Pointer" << endl;

    int i = 10;
    cout << &i << endl ; // &는 일반변수 앞에서 사용될 때 일반변수의 주소를 리턴! >> 값이 변한다고 해서 변하지 않음

    int *p = &i; // (변수타입)* 포인터 변수  << 이렇게 선언. 
    cout << p << endl;

    cout << *p << endl << endl;  // *(에스터리스크) 기호가 이와 같이  pointer 변수에게 붙으면 역참조 연산자가 되어 해당 pointer 변수의 주소에 저장된 값이 제공
}


//결과 
//Memory & Pointer
//000000A5ABD5FB44
//000000A5ABD5FB44
//10

3. Array to pointer decay

배열의 이름을 주소값으로 사용할 수 있음을 의미한다.(vector는 안됨 array만 가능)
이는 다르게 말하면, 배열의 이름을 포인터 변수로 취급해도 무방하다는 것이다.

#include <iostream>

using namespace std;

int main(){

    cout << "Array to Pointer decay" << endl;
    int array[3] = {1,2,3};
    int *pa = array;
    cout << pa << endl;
    cout << array << endl;
    cout << pa + 1 << endl;
    cout << &array[1] << endl << endl;
    
    
    //결과
    //000000A5ABD5FB2C
	//000000A5ABD5FB2C
	//000000A5ABD5FB30
	//000000A5ABD5FB30
    
}

4. 프로세스 메모리 구조와 정적할당, 동적할당.

4.1. 정적 할당

컴파일 단계에서 메모리를 할당하는 것을 의미한다.

  • BSS Segment: 전역, static, const 변수중 0으로 초기화, 혹은 초기화가 진행되지 않은 변수들이 할당.
  • Code/Text Segment: 프로그램의 코드가 돌아감

4.2. 동적 할당

런타임 단계에서 메모리가 할당되는 것을 의미한다.

  • Stack : 지역변수, 매개변수, 함수등에 의해 늘어나거나 줄어드는 메모리 영역. 함수 내의 변수 집합이 해당 함수의 다른 인스턴스 변수를 방해하지 않음
  • Heap : 동적으로 할당되는 변수를 담음. malloc, free 함수로 관리됨. vector가 대표적인 예시

5. 이터레이터

이터레이터는 컨테이너 요소(array, vector, list, map, set 등)에 접근하고, 순환하는 방법을 제공하는 객체로, 포인터의 일반화된 개념이다.(이터레이터의 경우 값을 직접적으로 제거 불가.)

#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> v;
    for(int i = 1; i<=5; i++ )v.push_back(i);
    for(int i = 0; i<5; i++){
        cout << i << "th value : " << *(v.begin() + i) << endl;
        cout << i << "th location : " << &*(v.begin() + i) << endl<< endl; // 주소값을 바로 반환하지 못하여 다음과 같이 &*사용해야함
    }
    for( vector<int>::iterator it = v.begin(); it != v.end(); it ++){
        cout << *it << endl;
    }
    auto it = v.begin();
    advance(it,3); // iterator 를 3증가시킴
    cout << endl;
    cout << *it <<endl;

    //cout << v.begin() //이렇게 하면 접근 안됨 

}
  • begin() : 컨테이너의 시작 위치 반환
  • end() : 컨테이너의 끝 위치 반환
  • advance(iterator, cnt) : iterator 위치를 cnt 만큼 증가시킴.

주의: 이터레이터는 분명 주소를 가르키고 있으나 바로 주소값을 리턴해주지는 않는다. 위와 같은 방식으로 * 이후 &를 붙여 찾아줘야한다.

2개의 댓글

comment-user-thumbnail
2023년 8월 17일

잘 읽었습니다. 좋은 정보 감사드립니다.

1개의 답글