본 내용은 POCU COMP3200: C++ 언매니지드 프로그래밍 강의를 토대로 작성하였습니다.
- 개체지향 프로그래밍(Object-Oriented Programming)
- OOP가 뭘까?
- 사람들이 세상을 바라보는 방식 = OOP의 핵심 개념
- 직관적
- OOP가 뭘까?
- 클래스
- 멤버 변수의 접근 권한
- C++의 기본 접근 권한은 private
- Java에서 접근 권한 제어 키워드를 생략하면 public도 private도 아님
- 그 변수는 해당 패키지 내에서 접근 가능
- 멤버 변수의 접근 권한
class Vector
{
int mX; //private 멤버 변수
int mY; //private 멤버 변수
}
- 접근 제어자(Access Modifier)
- public
- 누구나 접근 가능
- protected
- 자식 클래스에서 접근 가능
- private
- 해당 클래스에서만 접근 가능(개체에서가 아님)
- public
- 개체 생성
- 스택
- 예약된 로컬 메모리 공간 (작음, 일반적으로 1MB 이하)
- 함수 호출과 반환이 이 메모리에서 일어남
- 단순히 스택 포인터를 옮김
- 메모리를 할당 및 해제할 필요가 없음
- 스택에 할당된 메모리는 범위(scope)를 벗어나면 사라짐
- 변수와 매개변수를 위해 필요한 크기는 컴파일 도중에 알 수 있음
- 하지만 스택에 큰 개체를 많이 넣으면
- 스택 오버플로우(overflow)가 발생할 수 있음
- 성능이 느려 질 수도 있음
- 힙
- 전역 메모리 공간 (큼, ~GBs)
- 비어 있고 연속된 메모리 블록을 찾아야 함
- 프로그래머가 메모리를 직접 할당 및 해제해야 함
- 그렇지 않으면, 메모리 누수 발생
- C++은 언매니지드 언어
모든 함수는 스택 영역에서 작동함
스택에서 Foo 영역은 함수에서 코드가 아니라 함수에서 필요한 데이터를 담고 있는 스택
- 개체 배열 생성, 개체 소멸
- 개체 배열(Array)
뭐가 달라?
Java : 개체 같지만 개체의 레퍼런스! Vector 10개 만들어달란 얘기가 아니라 Vector을 10개 담을 수 있는 공간을 달란 얘기. 그 공간은 뭐냐? Vector의 레퍼런스
C++: 진짜 Vector을 열 개 만들어줌. 즉, 포인터를 담을 수 있는 공간 10개를 주는 게 아니라 실제로 Vector 10개 만들어주기 때문에 오브젝트 10개가 생성됨
Vector** list= new Vector*[10];
- Vector 포인터 10개를 담을 수 있는 배열.
- **의 의미: 하나는 배열이고 다른 하나는 배열이 아닌 실제 포인터. 벡터 포인터의 배열이라는 의미
- 개체 소멸
- [ ] 안넣으면 배열인 줄 모르고 첫번째 껏만 소멸자 호출하고 넘어가도 되겠네 하고 넘어감
- new를 사용한 뒤에는 꼭 delete를!
- 메모리 누수 방지를 위해 delete가 필수
- Java나 C#은?
- 마법적인 가비지 컬렉터(garbage collector)
- 메모리는 나중에 해제될 수도 있음
- 메모리 직접 관리 vs 편의
- 속도 vs 안전
- 멤버 변수 초기화
- 기본 값
- Java, C#
- x와 y는 모두 0으로 초기화 됨
- C++
- 값이 초기화되지 않음
- 전에 메모리 공간에 저장되어 있던 값을 사용
- 왜?
- 성능
- Java, C#
생각할 거리(면접질문): new/delete와 malloc()/free()의 차이점은?
malloc과 new의 차이점
malloc : 라이브러리에서 제공하는 메모리 할당 함수. free(변수명)로 할당 내용을 해제한다.
-형태: void *malloc(size_t size), 반환형 : *void 메모리 공간
-예: int a=(int*)malloc(50*sizeof(int));
- int형의 자료가 50개 들어갈 공간을 확보, a[0~49]의 인덱스로 접근 가능
- 프로그램 실행 중에 메모리를 할당받는 동적 메모리 할당 함수
new: 변수나 함수 객체의 생성자를 자동으로 호출하는 연산자, delete로 해제한다.
malloc/free | new/delete |
라이브러리가 제공하는 함수 | 프로그래밍 언어가 제공하는 연산자 -오버로딩 가능 |
필요한 메모리 양을 바이트 단위로 지정하고 void*를 리턴 - sizeof 연산자와 캐스트 연산자의 도움을 받아야 한다. - void를 리턴하는 이유는 다양한 형식(char, int, long등)에 적용되어야 하기 때문 |
할당할 타입을 지정하고 해당 타입의 포인터를 리턴 - 할당한 타입과 같은 타입의 포인터 변수로 대입만 받으면 된다 |
메모리 할당이 목적, 초기값 할당 불가 - 다른 예로 calloc 함수는 malloc 처럼 메모리 할당을 하는 점에선 같지만 모든 공간을 0으로 초기화한다. - calloc도 0으로 초기화 할 뿐이지 원하는 변수로 초기화는 불가 |
할당과 초기화를 동시에 진행할 수 있다. - int a = new int(123); - int a = new int(); a=123; + 위 두개의 예는 같은 결과를 낸다 |
오로지 메모리 공간 만을 할당 -생성자를 호출하지 않음 |
생성자를 자동으로 호출 - 생성자: 객체를 초기화하는 함수 |
할당된 메모리는 크기 변경이 가능 -realloc으로 재할당 가능 |
재할당이 불가능하다. - 새로운 변수를 만들고 그 안에 원래 변수를 만들어 대체하는 식으로 재할당해야한다 - 재할당 할 때마다 메모리 번지가 바뀐다. |
객체가 아니고 빈번하게 재할당을 한다면 malloc/free | 객체를 할당할 떄에는 반드시 new/ delete - delete는 소멸자라고 불리우는 함수가 호출되어 삭제된다 |
출처: 배고파서 까먹고 만든 블로그 :: C++ malloc/free와 new/delete의 차이점 (tistory.com)
'C++' 카테고리의 다른 글
[C++] 생성자, 초기화 리스트, 기본 생성자, 컴파일러가 하는 일, 생성자 오버로딩, 소멸자, const 멤버 함수, 구조체 vs 클래스 (0) | 2022.02.14 |
---|---|
#3. 상속, 캡슐화, 다형성, 가상 함수, 순수 가상함수, 추상 클래스 (0) | 2022.02.13 |
#2. 복사 생성자의 호출 시점 (0) | 2022.02.04 |
#1. 왜 C++인가? / 생성자와 소멸자 (0) | 2022.01.25 |
[C++] 참조(Reference) (0) | 2022.01.22 |
댓글