2011. 3. 4. 23:56

객체 포인터 배열 : 객체를 가리킬 수 있는 포인터로 구성이 되어 있는 배열

예제(new와 delete를 이용해서 어떻게 객체를 동적으로 생성 및 소멸하는지 알게 될것.)

 #include <iostream>
using std::cout;
using std::cin;
using std::endl;

class Point{
 int x;
 int y;
public :
 Point()
 {
  cout<<"Point() call!"<<endl;
  x=y=0;
 }
 Point(int _x, int _y)
 {
  x=_x;
  y=_y;
 }
 int GetX(){ return x;}
 int GetY(){ return y;}
 void SetX(int _x){ x=_x; }
 void SetY(int _y){ y=_y; }
};

int main()
{
 Point* arr[5];

 for(int i=0; i<5; i++)
 {
  arr[i] = new Point(i*2, i*3); //new에 의한 객체 동적 생성
 }
 for(int j=0; j<5; j++)
 {
  cout<<"x:  "<<arr[j]->GetX()<<' ';
  cout<<"y:  "<<arr[j]->GetY()<<endl;;
 }
 for(int k=0; k<5; k++)
 {
  delete arr[k]; //arr[k]가 가리키는 객체 소멸
 }
}


"new Point(i*2, i*3)"의 의미
:i*2와 i*3을 인자로 받을 수 있는 Point 클래스의 생성자를 호출하면서, Point 객체를 생성하라

=> 힙 영역에 생성. 생성된 객체의 주소 값이 Point*(Point 클래스의 포인터)형으로 반환될 것.

C에서 사용한 malloc 함수를 이용해서 객체 생성을 할 수 있을까? 없다!!
malloc 함수는 함수 호출 시 전달되는 인자만큼 단순히 메모리 공간만 할당하는 함수이기 때문이다. 즉 객체의 크기만큼 메모리 공간을 할당할 수는 있을 지라도, 생성자 호출은 이뤄지지 않는다. C++에서 이야기하는 객체의 조건을 만족시키려면, 생성자 호출은 반드시 이뤄져야 한다.
Posted by Triany
2011. 3. 4. 23:23
생성자와 동적할당

#include <iostream>
using std::cout;
using std::cin;
using std::endl;

const int SIZE=20;

class Person
{
 char *name;
 char *phone;
 int age;

public:
 Person(char* _name, char* _phone, int _age);
 void ShowData();

};
Person::Person(char* _name, char* _phone, int _age)
{
 
name = new char[strlen(_name)+1];
 strcpy(name, _name);
 phone = new char[strlen(_phone)+1];
 strcpy(phone, _phone);
 age = _age;
}

void Person::ShowData()
{
 cout<< " name: "<<name<<endl;
 cout<< " phone: " <<phone<<endl;
 cout<< " age: " << age<<endl;
}

int main()
{
 Person p("KIM", "013-113-1113 ", 22);
 p.ShowData();
 return 0;
}


결과적으로 객체 p는 main함수 내에서 생성되었으므로, 스택(stack)영역에 할당이 되겠지만, 생성자 내에서 메모리 공간을 동적을 할당하고 있기 때문에, 멤버 변수 name과 phone이 가리키는 메모리 공간은 힙(heap)이 된다.

=>이러한 형태의 초기화가 주는 이점은 메모리 공간을 효율적으로 사용할 수 있다는 것이다.


!!!문제 :!! 메모리 누수(유출)현상
=>해결 ? 소멸자에서 동적 해체!(delete)

 #include <iostream>
using std::cout;
using std::cin;
using std::endl;

const int SIZE=20;

class Person
{
 char *name;
 char *phone;
 int age;

public:
 Person(char* _name, char* _phone, int _age);
 
~Person();
 void ShowData();

};
Person::Person(char* _name, char* _phone, int _age)
{
 name = new char[strlen(_name)+1];
 strcpy(name, _name);
 phone = new char[strlen(_phone)+1];
 strcpy(phone, _phone);
 age = _age;
}

Person::~Person()
{
 
delete []name;
 delete []phone;
}

void Person::ShowData()
{
 cout<< " name: "<<name<<endl;
 cout<< " phone: " <<phone<<endl;
 cout<< " age: " << age<<endl;
}

int main()
{
 Person p("KIM", "013-113-1113 ", 22);
 p.ShowData();
 return 0;
}

!!!!!생성자 내에서 메모리를 동적 할당하는 경우, 이를 해제하기 위해서 반드시 소멸자를 정의해야 한다.!!




Posted by Triany
2011. 3. 3. 22:07
new : 힙 영역에 메모리 할당
<int 형 데이터 1개 저장>
int * arr = new int;

<길이가 size인 int형 배열 저장>
int * arr = new int[size];

NULL포인터를 리턴하는 new연산자
: 메모리 공간의 여의치 않다면(메모리를 할당만 하고, 적절히 소멸해 주지 않을 경우에 발생) new연산자에 의한 메모리 할당이 실패로 돌아갈 수도 있는 일. 이러한 경우 new 연산자는 NULL 포인터를 리턴..
NULL 포인터란 정수 0을 의미. 매크로로 정의되어 있는 상수 NULL을 사용해도 되고, 직접 0을 사용할 수도 있다.






delete 메모리 해제
<데이터 1개>
delete val;

할당된 메모리 공간이 배열인 경우, 2차 배열이건 3차배열이건 배열을 해제 할 때
delete[] arr;
이라 써주면 된다.


 #include <iostream>

using std::cout;
using std::cin;
using std::endl;

int main(void)
{
 //int형 데이터 1개 저장을 위한 메모리 할당
 int *val = new int;


 //길이가 size인 int형 배열을 위한 메모리 할당.
 int *arr = new int[size];
 ....

delete val;

delete []arr;

}


Posted by Triany