본문 바로가기
카테고리 없음

C++ 동적 메모리 할당

by 리승연 2018. 9. 16.
반응형

동적 메모리 할당

 

 C언어는 동적 메모리 할당 및 반환을 위해 malloc()/free() 등의 표준 C 함수를 이용하지만, C++은 newdelete 연산자를 이용한다.

 

new 연사자는 이라는 시스템 공간으로부터 메모리를 할당받고, delete 연산자는 할당받은 메모리를 힙으로 반환한다.

 

 

 

new와 delete 연산자

 

 new와 delete의 기본 활용

 

데이터타입 *포인터변수 = new 데이터타입;

delete 포인터변수;

 

 

 

 

 

new 연산자는 '데이터 타입'의 크키만큼 힙으로부터 메모리를 할당받고 주소를 리턴한다. 그 결과 '포인터변수'는 할당받은 메모리의 주소를 가진다.

 

delete 연산자는 '포인터 변수'가 가리키는 메모리를 힙으로 반환한다. '데이터타입'은 int, char, double 등 기본 타입과 구조체(struct), 클래스(class)이다.

 

1
2
3
4
5
6
7
int *pInt = new int//int 타입의 정수 공간 할당
char *pChar = new char//char 타입의 문자 공간 할당
Winkitee *pWinkitee = new Winkitee(); //Winkitee 클래스 타입의 객체 할당
 
delete pInt; //할당받은 정수 공간 반환
delete pChar; //할당받은 문자 공간 반환
delete pWinkitee ;//할당받은 객체 공간 반환
cs

 

 

동적 할당 메모리 초기화

 new를 이용하여 할당 받을때,

데이터타입 *포인터변수 = new 데이터타입(초깃값); 

 동적 할당 받을때 20과 'a'로 초기화 예,

1
2
int *pInt = new int(20); //20으로 초기화된 int 공간 할당
char *pChar = new char('a'); //'a'로 초기화된 char 공간 할당
cs

 

 

 delete 사용 시 주의 

 delete로 메모리 반환 시 적절하지 못한 포인터를 사용하면, 실행 오류가 발생한다.

 오류1

1
2
3
4
int n;
int *= &n;
delete p; //실행 오류, p가 가리키는 메모리는 동적 할당받은 것이 아님
 
cs

 오류2

1
2
3
int *= new int;
delete p; //정상적인 메모리 반환
delete p; //실행 오류, 이미 반환된 메모리를 중복 반환할 수 없음
cs

 

 

배열의 동적 할당 및 반환

기본 형식

데이터타입 *포인터변수 = new 데이터타입[배열의 크기]; //배열의 동적 할당
delete[] 포인터변수; //배열 메모리 반환

ex)

int len(12);

char *str =new char[len] //char타입의 메모리 동적 할당

 

 

 

배열 초기화 시 주의 사항

 

배열 delete 시 주의

1
2
3
4
int *= new int[10];
delete p; //비정상 반환, delete [] p;로 해야함
int *= new int;
delete[]q; //비정상 반환, delete q;로 해야함
cs

 

 

 

 

 

 

 

객체의 동적 생성 및 반환

 

new를 이용한 객체의 동적 생성과 생성자

 

클래스이름 *포인터변수 = new 클래스이름; // 기본 생성자 호출
클래스이름 *포인터변수 = new 클래스이름(생성자매개변수리스트); //매개 변수 있는 생성자 호출

 

 

 

Winkitee 타입의 객체 생성 예제

 

1
2
Winkitee *new Winkitee; //생성자 Winkitee() 호출, p = new Winkitee();와 같음
Winkitee *new Winkitee(23); //생성자 Winkitee(23) 호출
cs

 

 

 

delete를 이용한 객체 반환 소멸자

 

1
delete 포인터변수;
cs

 

 

delete 실행되면, 객체 반환 직전에 객체의 소멸자가 실행된다.

 

1
2
3
4
5
Winkitee *= new Winkitee; //생성자 Winkitee() 호출, p = new Winkitee();와 같음
Winkitee *= new Winkitee(23); //생성자 Winkitee(30) 호출
 
delete p; //Winkitee 객체 반환
delete q; //Winkitee 객체 반환
cs

 

 

 

 

 

객체 배열의 동적 생성 및 반환

 

 객체 배열의 동적 생성과 생성자

 

클래스이름 *포인터변수 = new 클래스이름[배열의 크기];

 

 

 

 객체 반환과 소멸자

 

1
delete[]포인터변수; //포인터변수가 가리키는 배열을 반환한다.
cs

 

 

 

 

 

 


 

 

 

▶this 포인터(this pointer)

 

 

 

this는 객체 자신에 대한 포인터로서 클래시의 멤버 함수 내에서만 사용된다. this는 전역 변수도 아니고 함수 내에 선언된 지역 변수도 아니다. this는 객체의 멤버 함수가 호출될 때, 컴파일러에 의해 보이지 않게 전달되는 객체에 대한 주소이다. (this pointer=객체 구별 역할)

 

 

 

this는 어디에 사용되나?

 

intsant 메소드만, static은 사용 불가능

 

 

 

this가 필요한 2가지 경우

 

 아래 생성자 함수 경우 this->생략 가능

1
2
3
Winkitee() {
    this->num = 1//thie->를 생략하고 num = 1;로 해도 무관
}
cs

 

 ●멤버 변수의 이름과 동일한 이름으로 매개 변수 이름을 짓고자 하는 경우

1
2
3
4
5
6
7
class Winkitee {
    int num;
    Winkitee(int num) {
        this->num = num;\
        //멤버 num//매개변수 num
    }
};
cs

 

 ●객체의 멤버 함수에서 객체 자신의 주소를 리턴 할 때, this 반드시 필요

1
2
3
4
5
6
7
class Winkitee {
public:
    Winkitee*f() {
        ...
        return this;
    }
};
cs

 

 

연산자 중복을 구현할 때, 이런 경우가 많이 발생한다. this 없이는 연산자중복 할 수 없는 경우도 있다.

 

 

 

 예제

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
28
29
#include <iostream>
using namespace std;
 
class Obj {
private:
    int a;
 
public:
    //Obj() { cout << "생성자"; };
    Obj() { this->= 0; };
    ~Obj() { cout << "소멸자"; }; //소멸자함수 디폴드는 자신 사용하지 않을 경우만 .!
 
    Obj(int a) {
        this->= a;
    }
 
    void setA(int a) { //void setA(Obj *this int a)
        this->= a;
    }
 
    int getA(int a) {
        return a;
    }
};
 
void main() {
    Obj *= new Obj;
    delete p;
}//소멸자
cs
반응형