배열
int b[5]= {1,2,3} 하면 나머지 칸들은 0 으로 초기화된다
int c[] = {1,2,3,4,5} 하면 자동으로 크기 5로 정의됨
동적메모리할당 : 프로그램동작중에 기억공간의 필요성 및 소요량을 결정하여 필요한 공간을 할당하는 것
- 기억공간의 생성시점 ;new연산자의 실행시점
- 기억공간의 소멸시점 : delete연산자의 실행시점
포인터 변수가 할당된 기억공간을 가리키게 함
메모리 할당 연산자
ptrVar = new TypeName;
ptrVar = new TypeName[n];
메모리 반납 연산자
delete ptrVar;
delete [] ptrVar;
int * intPtr
intPtr = new int; 정수하나를 저장할수있는 메모리를 할당받음
*intPtr =10;

delete intPtr;
intPtr =nullptr; //c++11부터 도입된 널포인터

l-value 참조

참조변수는 참조대상의 별명처럼 사용할 수 있음
l-value :실체가 있는대상(l-value)에 대한 참조
int a=10;
int& aRef = a;
aRef=100; // a도 100이됨
refVar는 varName를 참조함
참조는 반드시 초기화가 필요하다
a의 별명이 aRef가 된 것.
const 참조
참조변수가 참조하는 대상을 읽게만할수있고 값을 바꿀수는 없음
int x {10} ;
const int& xRef =x;
xRef +=10; // 오류
참조가 포인터와 다른점
참조 변수를 이용하여 값을 읽거나 저장할 때 참조 대상변수를 사용하는 형식과 동일함
참조변수는 초기화를 통해 반드시 어떤 대상을 참조해야함
- 초기화되지않은 상태로 인해 무엇을 참조하고있는지 알수 없는 상황은 발생하지 않음
참조변수는 초기화를 통해 지정된 참조 대상을 바꿀 수 없어 참조의 유효기간 동안 하나의 대상만 참조할 수 있음
r-value 참조란?
- 사용한 후에 그 값을 더이상 가지고 있을 필요가 없는 대상 참조
용도: 객체의 값을 다른 객체로 이동
int arr[10];
for ( : arr)
cin >> a;
int a로 하면 문제가있다
범위 기반 for 루프에서 a가 배열의 복사본이라는 점입니다. 범위 기반 for 루프에서 a는 배열 arr의 요소를 복사한 값이므로, 배열 arr의 원소가 직접 수정되지 않습니다.
c++의 경우 구조체내에 함수정의 가능
클래스 내에 자료를 저장하는 항목 정의 가능
구조체와 클래스의 구성 요소(멤버)에 접근하는 방식은 동일합니다.
- 만약 포인터를 통해 접근할 경우, 구조체와 클래스 모두 -> 연산자를 사용합니다.
- 포인터가 아닌 객체를 통해 직접 접근할 경우, 구조체와 클래스 모두 . 연산자를 사용합니다.
C언어와 C++의 구조체 차이
C 언어의 구조체
- 데이터 묶음: C에서 구조체는 단순히 여러 개의 변수를 묶어서 하나의 데이터 타입으로 사용하는 용도로 사용됩니다.
- 멤버 함수: C의 구조체는 함수를 포함할 수 없습니다. 구조체는 데이터만을 저장하기 위한 용도입니다.
- 접근 제어자: C에서는 모든 구조체 멤버가 기본적으로 public입니다. C 언어는 구조체 멤버에 대한 접근 제어를 제공하지 않습니다.
C++의 구조체
- 멤버 함수: C++에서는 구조체가 데이터뿐만 아니라 함수도 포함할 수 있습니다. 구조체는 클래스와 거의 동일하게 동작하며, 객체지향 프로그래밍을 지원합니다.
- 접근 제어자: C++에서는 구조체 멤버에 대해 접근 제어자가 존재합니다. 기본적으로 public이지만, private 또는 protected를 지정할 수도 있습니다.
- 상속: C++의 구조체는 클래스와 동일하게 상속을 지원합니다. 구조체 간 상속 관계를 형성할 수 있으며, 이를 통해 구조체 간에 기능을 공유할 수 있습니다.
- 생성자 및 소멸자: C++의 구조체는 **생성자(constructor)**와 **소멸자(destructor)**를 가질 수 있습니다. 따라서 객체를 초기화하거나 객체가 소멸될 때 동작을 정의할 수 있습니다.
- C 언어: C의 구조체는 순수한 데이터 묶음으로, 클래스와 같은 개념이 존재하지 않습니다.
- C++ 언어: C++의 구조체는 사실상 클래스와 거의 동일합니다. 유일한 차이점은 기본 접근 제어자가 다르다는 점입니다.
- 구조체의 기본 접근 제어자는 public입니다.
- 클래스의 기본 접근 제어자는 private입니다.
- C 언어: 접근 제어자가 없으므로 모든 멤버가 기본적으로 public입니다. 구조체 외부에서 모든 멤버에 접근할 수 있습니다.
- C++ 언어: C++에서는 구조체에도 접근 제어자를 사용할 수 있습니다. 멤버 변수를 private, protected, 또는 public으로 지정할 수 있으며, 객체지향 프로그래밍에서 중요한 캡슐화가 가능합니다.
- C 언어: 상속과 다형성은 지원되지 않습니다. C 언어는 객체지향 프로그래밍을 지원하지 않기 때문에 이러한 기능은 사용할 수 없습니다.
- C++ 언어: C++의 구조체는 상속을 지원하며, 다형성을 구현할 수 있습니다. 구조체는 부모 구조체 또는 클래스로부터 멤버와 메서드를 상속받을 수 있으며, 가상 함수 등을 통해 다형성도 구현 가능합니다.
요약
특징C 구조체C++ 구조체
데이터 | 단순 데이터 묶음 | 데이터와 함수 포함 가능 |
접근 제어자 | 없음, 모든 멤버가 public | public, private, protected 사용 가능 |
상속 | 지원되지 않음 | 클래스처럼 상속 가능 |
생성자/소멸자 | 없음 | 생성자/소멸자 가능 |
다형성 | 지원되지 않음 | 가상 함수 등을 사용하여 다형성 구현 가능 |
기본 접근 제어자 | public | 기본 접근 제어자는 public (클래스는 private) |
C++의 new연산자 C언어의 malloc()함수 차이
C++에서 new 연산자를 사용하여 동적 메모리를 할당하는 것과 C에서 malloc() 함수를 사용하여 동적 메모리를 할당하는 것 사이에는 몇 가지 중요한 차이점이 있습니다. 이 차이점들은 주로 초기화 여부, 타입 안전성, 소멸자 호출 여부에 관련됩니다. 아래에서 두 가지 방법을 비교하고 차이점을 설명하겠습니다.
C++의 new연산자
- 기능:
- new 연산자는 타입에 맞춰 메모리를 할당하고, 해당 타입의 생성자를 호출하여 객체를 초기화합니다.
- 기본적으로 할당된 메모리 공간이 타입에 맞게 초기화됩니다. 예를 들어, 기본 생성자가 있는 객체의 경우 생성자가 호출됩니다.
- 배열을 할당할 때는 new[]를 사용하며, 할당된 배열의 각 요소에 대한 기본 생성자가 호출됩니다.
- 메모리를 해제할 때는 delete와 delete[]를 사용합니다.
- 타입 안전성: new 연산자는 타입을 명확하게 지정하므로, 타입 변환이 필요 없습니다
int* ptr = new int; // int형 메모리 공간 할당 및 기본 값 초기화
*ptr = 5; // ptr이 가리키는 메모리에 값 할당
delete ptr; // 메모리 해제
malloc()함수
int* ptrVar = (int*)malloc(sizeof(int)); // 하나의 int 크기만큼 할당
int* arr = (int*)malloc(sizeof(int) * 10); // 배열 동적 할당
기능:
- malloc() 함수는 바이트 단위로 메모리를 할당합니다. 즉, 생성자 호출 없이 메모리만 확보합니다.
- 할당된 메모리는 초기화되지 않습니다. 즉, 쓰레기 값을 포함할 수 있습니다.
- 메모리를 해제할 때는 free() 함수를 사용합니다.
- 타입 안전성: malloc() 함수는 반환 값이 void* 포인터이므로, 타입을 맞추기 위해 명시적 캐스팅이 필요합니다.
int* ptr = (int*)malloc(sizeof(int)); // int형 메모리 공간 할당 (초기화 없음)
*ptr = 5; // ptr이 가리키는 메모리에 값 할당
free(ptr); // 메모리 해제
2. 초기화 여부
- new: 할당된 메모리는 객체의 생성자를 호출하거나, 기본 타입의 경우 0으로 초기화되지 않지만, 직접 new int()와 같이 사용하면 0으로 초기화할 수 있습니다. 즉, 초기화는 옵션입니다.
- malloc(): 할당된 메모리는 초기화되지 않습니다. 만약 초기화된 메모리가 필요하다면, memset() 또는 별도로 값을 지정해야 합니다. 초기화되지 않은 메모리는 쓰레기 값을 가질 수 있습니다.
- int* ptr = (int*)malloc(sizeof(int)); // 초기화되지 않은 메모리 할당
memset(ptr, 0, sizeof(int)); // 0으로 초기화
3. 타입 안전성
- new: 타입에 맞게 메모리가 할당되므로 타입 안전성이 보장됩니다. 반환되는 포인터의 타입을 명시적으로 캐스팅할 필요가 없습니다.
int* ptr = new int; // 타입 안전
- malloc(): malloc()은 **타입을 모르기 때문에 void***를 반환합니다. 따라서 할당된 메모리를 사용하려면 명시적인 캐스팅이 필요합니다.
int* ptr = (int*)malloc(sizeof(int)); // 명시적 캐스팅 필요
4. 생성자 및 소멸자 호출
- new: 클래스 객체를 동적 할당할 때 생성자가 호출됩니다. 또한, delete를 사용하면 소멸자가 호출되어 객체의 메모리가 안전하게 해제됩니다.
MyClass* obj = new MyClass(); // 생성자 호출delete obj; // 소멸자 호출
- malloc(): 생성자나 소멸자와 같은 개념이 없기 때문에, 객체의 생성 및 해제 시 생성자나 소멸자가 호출되지 않습니다. 만약 생성자나 소멸자를 수동으로 호출해야 하는 경우가 있으면 이를 명시적으로 처리해야 합니다.
MyClass* obj = (MyClass*)malloc(sizeof(MyClass)); // 생성자 호출 안 됨
5. 메모리 해제
- new: 동적으로 할당된 메모리는 반드시 delete 또는 delete[]를 사용해 해제해야 합니다.
delete ptr; // 단일 객체 메모리 해제delete[] arr; // 배열 메모리 해제
- malloc(): malloc()로 할당된 메모리는 반드시 free()를 사용해 해제해야 합니다.
free(ptr); // 메모리 해제
요약 비교표
특징 C++ new/delete C malloc/free
초기화 여부 | 기본적으로 생성자가 호출되어 초기화될 수 있음 | 초기화되지 않음 |
타입 안전성 | 타입 안전, 명시적 캐스팅 불필요 | void* 반환, 명시적 캐스팅 필요 |
생성자/소멸자 | 생성자와 소멸자가 호출됨 | 생성자와 소멸자가 호출되지 않음 |
메모리 해제 방법 | delete와 delete[] 사용 | free() 사용 |
배열 할당 | new[]로 동적 배열 할당 | malloc()로 메모리 할당 |
오류 처리 | 실패 시 std::bad_alloc 예외 발생 (처리 가능) | 실패 시 NULL 반환 (체크 필요) |
결론
- C++에서 new/delete: C++ 스타일의 동적 메모리 할당 및 해제 방식으로, 타입 안전성, 생성자/소멸자 호출, 예외 처리 등의 장점이 있습니다.
- C에서 malloc()/free(): C 스타일의 동적 메모리 할당 방식으로, 단순히 메모리만 할당하고 초기화나 객체 관리가 따로 필요합니다. 타입 안전성도 보장되지 않으며, 명시적인 캐스팅이 필요합니다.
일반적으로 C++에서는 new/delete를 사용하는 것이 더 안전하고 효율적입니다.
c++에서도 여전히 **malloc()**를 사용할 수 있지만, 권장되지 않습니다. C++에서 제공하는 new/delete 연산자가 malloc()/free()에 비해 여러 가지 면에서 더 적합하고 안전하기 때문입니다.
- 객체 지향 프로그래밍에 맞는 기능:
- C++의 new 연산자는 생성자 호출을 통해 객체를 초기화합니다. 반대로, malloc()은 단순히 메모리를 할당할 뿐, 생성자를 호출하지 않기 때문에 객체가 제대로 초기화되지 않을 수 있습니다.
- delete는 소멸자 호출을 통해 객체가 메모리에서 해제될 때 자원을 정리할 수 있도록 합니다. free()는 소멸자를 호출하지 않으므로, 객체가 제대로 소멸되지 않고 리소스 누수가 발생할 가능성이 있습니다.
- 타입 안전성:
- new 연산자는 명시적인 타입 캐스팅이 필요 없기 때문에 타입 안전성을 보장합니다. malloc()은 void*를 반환하므로, 적절한 타입으로 명시적으로 캐스팅해야 하는데, 이 과정에서 오류가 발생할 수 있습니다.
- 예외 처리:
- new는 메모리 할당에 실패할 경우 예외(std::bad_alloc)를 발생시킵니다. 이를 통해 메모리 부족 상황을 명확히 처리할 수 있습니다.
- 반대로, malloc()은 메모리 할당 실패 시 **NULL**을 반환합니다. 이 반환 값을 매번 확인하고 처리하지 않으면 문제가 발생할 수 있습니다.
- RAII (Resource Acquisition Is Initialization):
- C++는 RAII 개념에 따라 자원(메모리, 파일 핸들 등)의 획득과 초기화를 하나로 묶는 패턴을 장려합니다. new/delete는 이러한 개념을 더 잘 반영합니다. 또한, 스마트 포인터(std::unique_ptr, std::shared_ptr)를 사용하여 동적 메모리를 자동으로 관리할 수 있습니다.
예시 비교
C++에서 malloc()를 사용하는 경우
C++에서도 malloc()를 사용하는 상황이 있을 수 있지만, 이는 주로 레거시 코드나 특정한 이유가 있을 때입니다. 예를 들어, 어떤 C 라이브러리와 상호작용할 때, 그 라이브러리의 메모리 할당 방식이 malloc()를 기반으로 할 경우입니다.
결론
- C++에서는 new/delete를 사용하는 것이 권장됩니다. 이 방식이 더 안전하고, 객체 지향 프로그래밍의 원칙과 잘 맞으며, 초기화와 소멸자를 지원합니다.
- malloc()/free()는 여전히 사용 가능하지만, 일반적으로 C++ 코드에서는 new/delete를 사용하거나, 더 나아가 스마트 포인터(std::unique_ptr, std::shared_ptr)를 사용하는 것이 훨씬 더 바람직합니다.
'수업 > C++' 카테고리의 다른 글
8,9연산자 다중정의 (0) | 2024.11.25 |
---|---|
7.클래스와 객체 -임시객체,묵시적형변환,위임생성자 ,초기화리스트생성자 (0) | 2024.11.25 |
5,6 클래스와 객체 (const, 생성자,소멸자,rvalue참조,static) (4) | 2024.11.13 |
4강 함수 (1) | 2024.10.01 |
1강2강 c++소개 (1) | 2024.09.30 |