[ C++ 7_2.정적,동적 메모리, 배열, 객체 동적 할당]

·2022년 8월 2일
0

C++_Study

목록 보기
14/25

#220802~ 220803

#7-4. 동적메모리를 사용하는 이유

  • 지역변수

    • 자신의 지역 내에서만 유효, 함수가 반환되면 지역변수는 사라짐
  • 전역변수

    • 프로그램이 끝날 떄 까지 값 유지,
    • 프로그램의 모든 부분에서 접근 가능
    • 이해하기 어렵고 유지보수 어려움

* 동적 메모리를 사용하는 이유

  • 1). 지역 변수는 지역내에서만 유효한데 전역변수처럼 '프로그램이 끝날 때까지 값을 유지'하고 싶은 경우
  • 2). 프로그램을 실행할 때(runtime) '메모리의 양'을 결정해야 하는 경우
  • 3). 지역변수가 저장되는 스택은 한정되어 있어서 너무 큰 크기는 할당이 어려움 스텍공간이 부족하면 stack overflow 오류/ heap에 할당해야 함
  • 4). 실행시간에 할당되어 사용되는 메모리 블록 (heap)
  • 5). 동적메모리의 단점: 스택보다 느림

#7-5. 정적 vs 동적 메모리 할당

[정적 메모리 할당]

  • 컴파일 시 필요한 메모리 할당
  • 배열 int array[32]; / 항상 128byte 공간 확보
  • 사용하지 않는 메모리까지 잡아 낭비
  • 너무 큰 메모리 할당 불가
  • 보통 수 KB까지는 스택 사용, 그 이상은 heap에 할당

[동적 메모리 할당]

  • 실행시 필요한 메모리(heap) 할당
  • 필요한 만큼만 잡음
  • 메모리의 주소를 사용하여 접근
  • malloc()/free()사용
  • new/delete 사용
    • new: 메모리 할당, 할당된 메모리 시작주소 리턴됨
    • delete: 할당 받은 메모리 해제

#7-6. 동적메모리할당 실습

[c vs c++]
동적 메모리의 할당과 해제: new와 delete
정적할당: int x;
int x[5];

<기본 자료형>

  • 포인터 변수=new 자료형;
int *pi=new int;
  • 포인터 변수=new 자료형(초기값);
int *pi=new int(2); // 초기값을 줄 경우 
  • 해제: delete 포인터 변수;
    delete pi;

<배열>

  • 포인터 변수 = new 배열;
  • 정수형 자료 5개를 저장하기 위한 20바이트 공간 할당, pi는 첫번째 공간의 주소
int *pi=new int[5];
  • 해제: delete[] 포인터 변수;
    delete[]pi; // 주의:'[]' 써야함

[new와 delete]

  • new는 메모리를 동적으로 할당하고, 할당된 메모리에 대한 주소를 반환하는 연산자이다.
    • malloc() 함수와 마찬가지로, 요구한 만큼의 메모리가 충분하지 않으면 new는 null포인터를 반환한다.
int *pi=new int; 
int *pi = (int*)malloc(sizeof(int)); 
  • delete는 free() 함수와 마찬가지로, 더 이상 필요없는 메모리를 해제한다. (해제하지 않으면 메모리 누수가 발생하여 다른 프로그램에서도 해당 메모리는 사용하지 못함)
delete pi; 
free(pi);

<new와 delete의 장점>

  • 하나의 정수에 대한 메모리 할당과 해제
  • 'new' 사용해서 4바이트의 공간/ 메모리 할당! (heap에)

#7-7. 배열의 크기를 실행시 결정

#7-8. 실행시 필요한 만큼의 동적 메모리 할당

  • c++에서 배열의 이름은 그 첫 번째 방의 '주소'입니다
int main()
{
    int i, n;
    int* num;               //num이 배열이 아니였는데 왜 바뀌었지? 고민할 필요 ㅌ
    std::cout << "몇개의 숫자를 입력하시겠습니까==" << std::endl; 
    std::cin>>i; 

    num = new int[i];       	//new로 동적 메모리 할당/ 배열이름 num의 첫번쨰 방의 주소 
    if (num == NULL) exit (1);  // 종료 
    for (n = 0; n < i; n++)
    {
        std::cout << "숫자를 입력하십시오: " << std::endl; 
        std::cin >> num[n]; //배열의 주소는 첫 번째 방 주소이다
    }
    
    std::cout << "당신이 입력한 숫자는: " << std::endl;  
    for(n=0; n<i; n++)
        std::cout << num[n] << ", ";
    delete[] num; 
    return 0;
    
}

#7-9. 객체 동적 할당

// getter, setter 쭉쭉
// 만들어진 객체는 반드시 다시 delete를 해주어야 함

class Dog{
private:
    int age;
public:
    int getAge();
    void setAge(int a);
};
int Dog::getAge()
{
    return age;
}
void Dog::setAge(int a)
{
    age=a;
}

int main()
{   
    Dog *dp;
    dp=new Dog;         //Dog *dp=new Dog (두줄을 한줄로도 가능) 
    
    if(!dp){
        std::cout << "메모리 할당 불가!"; 
        return 1;
    }

    dp -> setAge(5);    //pointer
    std::cout << "메모리에 할당된 값은?" << " " << dp->getAge() << " " << "입니다." << std::endl; 

    delete dp; 		//이렇게 해야 heap에서 사라진다 
    return 0;
}

print => 메모리에 할당된 값은? 5 입니다.

✭ 배열 객체 동적 할당 (new Dog[10]) set으로 설정하고 get으로 받기 ✭

class Dog{
private:
    int age;
public:
    int getAge();
    void setAge(int a);
};
int Dog::getAge()
{
    return age;
}
void Dog::setAge(int a)
{
    age=a;
}

int main()
{   
    Dog *dp=new Dog[10];       // 객체배열 할당   
    if(!dp){
        std::cout << "메모리할당이 되지 않았습니다."; 
        return 1;
    }
    
    for (int i=0; i<10; i++){
        dp[i].setAge(i);}
    for (int i=0; i<10; i++){
        std::cout << i << " 번쨰 객체의 나이는" << dp[i].getAge() << "입니다." << std::endl; 
    }
    
    delete []dp; 
    return 0;
}

-- print
0 번쨰 객체의 나이는0입니다.
1 번쨰 객체의 나이는1입니다.
2 번쨰 객체의 나이는2입니다.
3 번쨰 객체의 나이는3입니다.
4 번쨰 객체의 나이는4입니다.
5 번쨰 객체의 나이는5입니다.
6 번쨰 객체의 나이는6입니다.
7 번쨰 객체의 나이는7입니다.
8 번쨰 객체의 나이는8입니다.
9 번쨰 객체의 나이는9입니다.
profile
Hakuna Matata

0개의 댓글

관련 채용 정보