#include <iostream>
using namespace std;
int main()
{
int *arr;
arr = new int[10];
for (int i = 0; i < 10; i++)
arr[i] = i + 1;
int sum = 0;
for (int i = 0; i < 10; i++)
sum += arr[i];
cout << sum << endl;
delete[] arr;
return 0;
}
배열을 할당할 경우, (1차원 배열에서) 받는 것은 그대로 포인터이다.
new로 배열 메모리를 할당받을 때, 자료형 뒤에 "[크기]" 를 이어서 쓴다. c에서 처럼 byte수로 넘겨야 해 sizeof(int)를 곱하거나 하는 일은 없다. 이미 자료형이 언급되었으므로 "크기"만 주면 된다.
delete로 배열 메모리를 해제할 때는 "delete[]" 로 쓴다.
[] 를 붙이면 포인터가 배열을 할당받았으므로 연달아 많은 칸의 메모리를 해제해야 한다는 것을 컴퓨터에 알려주어 이어진 메모리를 한번에 다 해제한다.
#include <iostream>
using namespace std;
class Student
{
private:
string name;
int score;
public:
Student();
Student(string, int);
int getScore();
};
int main()
{
int num;
string tname;
int tscore;
Student *student_arr;
cout << "enter number of students:";
cin >> num;
student_arr = new Student[num];
for (int i = 0; i < num; i++)
{
cout << i + 1 << " 'th student's name:";
cin >> tname;
cout << i + 1 << " 'th studnet's score(0~100): ";
cin >> tscore;
student_arr[i] = Student(tname, tscore);
}
int sum_score = 0;
for (int i = 0; i < num; i++)
sum_score += student_arr[i].getScore();
cout << "Score's sum:" << sum_score << endl;
delete[] student_arr;
return 0;
}
Student::Student() : name(""), score(0) {}
Student::Student(string tname, int tscore) : name(tname), score(tscore) {}
int Student::getScore()
{
return score;
}
입력받는 변수 num이 배열의 크기를 결정한다. 이때 배열의 크기를 사용한 메모리의 동적할당을 할 때, Student[num] 과 같은 형식으로 해주었다.
가리키는 곳이 정해지지 않은 포인터로, 가리키는 주소를 초기화하지 않았거나, 동적 메모리 할당 후 해제를 한 직후에 발생한다. 후자의 경우, 가리키던 메모리가 해제되어 그 주소는 더 이상 쓸모 없다. 이런 주소에 " *, [], -> " 같은 연사자들로 접근하려 하면 심각한 문제가 발생한다.
#include <iostream>
using namespace std;
int main(){
int *p = new int[3];
p[0] = 4;
p[1] = 1;
p[2] = 7;
cout << p[0] << endl;
cout << p[1] << endl;
cout << p[2] << endl;
delete[] p;
cout << p[0] << endl;
cout << p[1] << endl;
cout << p[2] << endl;
return 0;
}
메모리 할당 해제 이후 그 메모리에 젖ㅂ근하려 하면 쓰레기값 밖에 건지지 못한다.
이미 해제된 메모리를 참조하지 않기 위해 해제 후 해당 포인터를 NULL pointer로 만든다. NULL pointer로 접근하려 하면 실행 중 에러가 떠 논리적 오류를 잡을 수 있다.
#include <iostream>
using namespace std;
int main(){
int *p = new int(12);
int *q = new int(45);
cout << p << " " << q << endl;
q = p;
cout << p << " " << q << endl;
return 0;
}
p,q가 서로다른 동적 메모리를 가리키고 있는데, q=p; 명령으로 인해 q가 가리키고 있던 동적 메모리에 접근할 방법이 사라졌다. 이렇게 되면 q가 가리키고 있던 동적 메모리를 해제할 수 없게 된다.
#include <iostream>
using namespace std;
int *getPtr()
{
int n = 5;
int *p = &n;
return p;
}
int main()
{
int *q;
q = getPtr();
cout << *q << endl;
return 0;
}
포인터 형(주소값)을 return하는 함수를 만들었다. return 값이 지역변수인 n의 주소값인데, 함수 종료 후 그에 속한 지역변수 n도 날아가게 되어 return값은 dangling 포인터가 된다. //컴파일러에 따라 쓰레기값이 아닌 n값이 나오기도 한다..
#include <iostream>
using namespace std;
int *getPtr()
{
int *p = new int(5);
return p;
}
int main()
{
int *q;
q = getPtr();
cout << *q << endl;
delete q;
return 0;
}
함수 안에서 동적 메모리를 할당받아 그 주소를 넘겨줬다면, 메모리는 heap에 별개 위치하므로, 항상 원했던 값인 *p값이 나오게 된다. 함수가 끝나도 메모리는 함수 종료와 관계없이 남아있다. 단, 이 메모리는 언젠가는 해제해 줘야 한다. 다라서 마지막 줄에 delete해 주었다.