메모리
프로그램 실행 시 자유롭게 할당하고 해제할 수 있는 힙(heap) 메모리 공간이 생김
-> 스택(stack)과 다르게 메모리 누수를 프로그래머가 담당해야 함.
C언어의 특징:
- 메모리 관리 방식
- 정적/전역 변수: 컴파일 시점에 주소값이 확정
- 동적 할당 변수: malloc/free를 통해 런타임에 메모리를 관리
- 프로그래머 제어 중시
- malloc은 void*를 반환하여 프로그래머가 명시적 타입 변환
- 메모리 초기화를 프로그래머가 직접
C++의 특징:
- 메모리 관리 방식
- 정적/전역 변수: C와 동일하게 컴파일 시점에 주소값이 확정
- 동적 할당 변수: new/delete를 통해 런타임에 메모리를 관리
- 타입 안전성 중시
- new는 지정된 타입의 포인터를 직접 반환
- 생성자를 통해 자동으로 초기화
- 실패 시 예외 처리를 제공
- 객체 지향적 접근
- RAII(Resource Acquisition Is Initialization) 패턴 지원
- 스마트 포인터를 통한 자동 메모리 관리 가능
- 생성자/소멸자를 통한 자원 관리
C는 프로그래머에게 더 많은 제어를 제공하는 반면,
C++은 안전성과 편의성을 더 강조합니다.
/* new, delete 사용*/
#include <iostream>
int main() {
int* p = new int;
*p = 10;
std::cout << *p << std::endl;
delete p;
return 0;
}
지역 변수를 강제로 delete로 해제하려고 하면 다음과 같은 Heap이 아닌 공간을 해제하려고 한다.

#include <iostream>
int main()
{
int arr_size;
std::cout << "배열의 크기를 입력하세요: ";
std::cin >> arr_size;
int* arr = new int[arr_size];
for (int i = 0; i < arr_size; i++)
{
arr[i] = i;
}
for (int i = 0; i < arr_size; i++)
{
std::cout << arr[i] << std::endl;
}
delete[] arr;
return 0;

C/ C++ 비교
인적사항을 적는 프로그램이 있다고 하자.
#include <iostream>
typedef struct Person {
char name[30]; // 이름
int age;// 나이
float height; // 키
double weight; // 몸무게
}Person;
void create_person(Person* person) {
std::cout << "학생의 이름? ";
std::cin >> person->name;
std::cout << "학생의 나이? ";
std::cin >> person->age;
std::cout << "학생의 키(cm)? ";
std::cin >> person->height;
std::cout << "학생의 몸무게(kg)? ";
std::cin >> person->weight;
}
// 사람 정보 출력 함수
void show_info(Person* person) {
std::cout << person->name << "의 정보" << std::endl;
std::cout << "나이 : " << person->age << "세" << std::endl;
std::cout << "키 : " << person->height << "cm" << std::endl;
std::cout << "몸무게 : " << person->weight << "kg" << std::endl;
}
// 사용 예시:
int main() {
Person* list[10];
int person_count = 0;
while(1){
std::cout << "1. 인적사항 추가하기" << std::endl;
std::cout << "2. 정보보기 " << std::endl;
std::cout << "3. 종료" << std::endl;
int input;
std::cin >> input;
switch (input) {
case 1:
list[person_count] = new Person;
create_person(list[person_count]);
person_count++;
break;
case 2:
std::cout << "현재 저장된 사람 목록:" << std::endl;
for (int i = 0; i < person_count; i++) {
std::cout << i + 1 << ". " << list[i]->name << std::endl;
}
int index;
std::cout << "번호를 선택하세요 (1-" << person_count << "): ";
std::cin >> index;
if (index < 1 || index > person_count) {
std::cout << "잘못된 번호입니다!" << std::endl;
break;
}
show_info(list[index - 1]);
break;
case 3:
std::cout << "프로그램을 종료합니다." << std::endl;
return 0;
default:
std::cout << "잘못된 입력입니다." << std::endl;
break;
}
}
for (int i = 0; i < person_count; i++) {
delete list[i];
}
return 0;
}
기존에 만들어진 프로그램은 사람으로 통틀어서 적었는데
이번에는 교사, 학생, 학부모까지 적어보자.

1. 코드 중복
// 1. 코드 중복 문제
void show_info_person(Person* p) {
std::cout << p->name << "의 정보" << std::endl;
std::cout << "나이: " << p->age << std::endl;
std::cout << "키: " << p->height << std::endl;
std::cout << "몸무게: " << p->weight << std::endl;
}
void show_info_student(Student* s) { // Person 정보 출력이 중복됨
std::cout << s->person.name << "의 정보" << std::endl;
std::cout << "나이: " << s->person.age << std::endl;
std::cout << "키: " << s->person.height << std::endl;
std::cout << "몸무게: " << s->person.weight << std::endl;
std::cout << "학년: " << s->grade << std::endl;
// ...
}
2. 배열 관리
int main() {
// 각각 다른 타입의 배열을 따로 관리해야 함
Person* person_list[10];
Student* student_list[10];
Teacher* teacher_list[10];
Parent* parent_list[10];
// 전체 구성원을 한번에 처리하고 싶어도 할 수 없음
// 각각 따로 처리해야 함
show_info_person(person_list[0]);
show_info_student(student_list[0]);
show_info_teacher(teacher_list[0]);
return 0;
}
class Person {
protected: // 상속받은 클래스에서 접근 가능
string name;
int age;
float height;
double weight;
public:
virtual void show_info() { // 한 번만 구현
cout << name << "의 정보" << endl;
cout << "나이: " << age << endl;
cout << "키: " << height << endl;
cout << "몸무게: " << weight << endl;
}
};
class Student : public Person { // Person의 모든 기능을 상속
int grade;
int class_num;
int student_num;
public:
void show_info() override { // Person의 정보 출력을 재사용
Person::show_info(); // 기존 Person의 show_info 호출
cout << "학년: " << grade << endl;
// ... 추가 정보만 출력
}
};
class Teacher : public Person { // Person의 모든 기능을 상속
string subject;
int career;
public:
void show_info() override {
Person::show_info(); // 중복 코드 없음!
cout << "과목: " << subject << endl;
// ... 추가 정보만 출력
}
};
int main() {
// 하나의 배열로 모든 타입 관리 가능!
Person* people[10];
people[0] = new Student();
people[1] = new Teacher();
// 한 번의 반복문으로 모든 구성원 처리 가능
for(int i = 0; i < 10; i++) {
people[i]->show_info(); // 각 타입에 맞는 show_info가 자동으로 호출됨
}
return 0;
}
#include <iostream>
#include <string>
#include <vector>
class Person {
protected:
std::string name;
int age;
float height;
double weight;
public:
Person(std::string n = "", int a = 0, float h = 0, double w = 0)
: name(n), age(a), height(h), weight(w) {}
virtual ~Person() {} // 가상 소멸자
virtual void inputInfo() {
std::cout << "이름? ";
std::cin >> name;
std::cout << "나이? ";
std::cin >> age;
std::cout << "키(cm)? ";
std::cin >> height;
std::cout << "몸무게(kg)? ";
std::cin >> weight;
}
virtual void showInfo() const {
std::cout << name << "의 정보" << std::endl;
std::cout << "나이: " << age << "세" << std::endl;
std::cout << "키: " << height << "cm" << std::endl;
std::cout << "몸무게: " << weight << "kg" << std::endl;
}
std::string getName() const { return name; }
};
class Student : public Person {
private:
int grade;
int class_num;
int student_num;
public:
void inputInfo() override {
Person::inputInfo();
std::cout << "학년? ";
std::cin >> grade;
std::cout << "반? ";
std::cin >> class_num;
std::cout << "번호? ";
std::cin >> student_num;
}
void showInfo() const override {
Person::showInfo();
std::cout << "학년: " << grade << std::endl;
std::cout << "반: " << class_num << std::endl;
std::cout << "번호: " << student_num << std::endl;
}
};
class Teacher : public Person {
private:
std::string subject;
int career;
public:
void inputInfo() override {
Person::inputInfo();
std::cout << "담당 과목? ";
std::cin >> subject;
std::cout << "경력(년)? ";
std::cin >> career;
}
void showInfo() const override {
Person::showInfo();
std::cout << "담당 과목: " << subject << std::endl;
std::cout << "경력: " << career << "년" << std::endl;
}
};
class SchoolManagement {
private:
std::vector<Person*> people;
public:
~SchoolManagement() {
for (Person* person : people) {
delete person;
}
}
void addPerson() {
std::cout << "1. 학생 추가" << std::endl;
std::cout << "2. 교사 추가" << std::endl;
int choice;
std::cin >> choice;
Person* person = nullptr;
switch (choice) {
case 1:
person = new Student();
break;
case 2:
person = new Teacher();
break;
default:
std::cout << "잘못된 선택입니다." << std::endl;
return;
}
person->inputInfo();
people.push_back(person);
}
void showPeopleList() const {
if (people.empty()) {
std::cout << "저장된 정보가 없습니다." << std::endl;
return;
}
std::cout << "현재 저장된 사람 목록:" << std::endl;
for (size_t i = 0; i < people.size(); i++) {
std::cout << i + 1 << ". " << people[i]->getName() << std::endl;
}
std::cout << "번호를 선택하세요 (1-" << people.size() << "): ";
size_t index;
std::cin >> index;
if (index < 1 || index > people.size()) {
std::cout << "잘못된 번호입니다!" << std::endl;
return;
}
people[index - 1]->showInfo();
}
};
int main() {
SchoolManagement school;
while (true) {
std::cout << "\n1. 인적사항 추가하기" << std::endl;
std::cout << "2. 정보보기" << std::endl;
std::cout << "3. 종료" << std::endl;
int input;
std::cin >> input;
switch (input) {
case 1:
school.addPerson();
break;
case 2:
school.showPeopleList();
break;
case 3:
std::cout << "프로그램을 종료합니다." << std::endl;
return 0;
default:
std::cout << "잘못된 입력입니다." << std::endl;
break;
}
}
}'ProgramingLagnuage > C++' 카테고리의 다른 글
| [C++] 객체지향 프로그래밍 (0) | 2025.01.01 |
|---|---|
| [C++] 템플릿 프로그래밍(template programming) (0) | 2024.10.18 |
| [C++] 사용자 정의 유형 - Structure (0) | 2024.09.23 |
| [C++] C++ 소개 (0) | 2024.09.22 |
| [C++] Class 주요 개념 (0) | 2024.09.22 |