14장 동적 메모리의 이해와 활용하기

14장 동적 메모리의 이해와 활용하기

1. 동적 메모리 이해하기

1) 메모리 할당 방식

  • 메모리 할당 방식
방식할당 시점메모리 반납메모리 관리
정적 메모리 할당프로그램프로그램비효율적
(static memory allocation)실행 전종료 후
동적 메모리 할당프로그램프로그램효율적
(dynamic memory allocation)실행 중실행 중

2) 동적 메모리 할당과 반납

  • 헤더파일 : <stdlib.h>
  • 동적 메모리 할당 관련 함수

|방식|설명|
|malloc()|메모리 할당(초기화 안함)|
|calloc()|메모리 할당(초기화 함|
|realloc()|메모리 재할당|
|free()|메모리 반납|


2. 동적 메모리 활용하기

1) 연결 리스트(linked list)

  • 데이터들을 연결 포인터를 이용하여 관리하는 자료구조(data structure)
  • 하나의 데이터들과 연결 포인터를 노드(node)라고 함
  • 시작 노드를 헤드(head)라고 하고, 데이터는 사용하지 않음

2) 연결 리스트의 종류

  • 단순 연결 리스트(singly linked list)
  • 원형 단순 연결 리스트(circular singly linked list)
  • 이중 연결 리스트(doubly linked list)
  • 원형 이중 연결 리스트(circular doubly linked list)

3) 단순 연결 리스트(singly linked list) 구현

  • 노드 구현
    • 구조체로 표현
    • 노드의 연결 포인터는 구조체 포인터로 표현
  • 데이터 노드 추가
    • 단순 연결 리스트의 마지막 노드 다음으로 추가
    • 마지막 노드의 연결 포인터에 데이터 노드 연결
  • 데이터 노드 삽입
    • 삽입하고자 하는 노드의 연결 포인터에 이전 노드의 연결 포인터 지정
    • 이전 노드의 연결 포인터에 삽입하고자 하는 노드의 주소값 지정
  • 데이터 노드 삭제
    • 이전 노드의 연결 포인터에 삭제하고자 하는 노드의 연결 포인터 지정
    • 메모리 반납

3. 단원 정리

1) 단순 연결 리스트를 이용하여 회원관리 프로그램 작성
2) 회원 추가, 삽입, 삭제, 검색, 목록보기 기능 구현
3) 회원 추가 시 마지막 노드에 추가
4) 회원 삽입 시 위치 입력받기
5) 회원 삭제 및 검색 시 회원이름 입력받기

#include "SLLtotal.h"
enum MENU { END, APPEND, INSERT, DELETE, SEARCH };
enum MENU select;

int main()
{
	NODE_t* data = NULL;

	initialize_SLL();  // 연결 리스트 생성(head 생성)

	while (head != NULL) {   // 연결 리스트가 생성되었으면 반복
		system("cls");   // 화면 지우기
		print_node();   // 연결 리스트 전체 화면 출력
		printf("1 : 데이터 추가\n");
		printf("2 : 데이터 삽입\n");
		printf("3 : 데이터 삭제\n");
		printf("4 : 데이터 검색\n");
		printf("0 : 종료\n");
		printf(">> ");
		scanf_s("%d", &select);  // 메뉴선택
		if (select == END) break;
		switch (select) {
		case APPEND :  // 추가
			data = new_node();    // 새로운 노드 입력받아서 생성
			if (data != NULL) append_node(data);     // 연결 리스트에 추가
			break;
		case INSERT :  // 삽입
			data = new_node();    // 새로운 노드 입력받아서 생성
			if (data != NULL) {
				int position = 0;
				printf("몇번째에 삽입할까요? : ");
				scanf_s("%d", &position);
				insert_node(position, data);  // 새로운 노드 삽입
			}
			break;
		case DELETE :  // 삭제
			delete_node();
			break;
		case SEARCH :  // 검색
			search_node();
			break;
		}
	}
}


#pragma once
#include <stdio.h>
#include <stdlib.h>

typedef struct MEMBER {
	char name[20];
	int age;
	struct MEMBER* next;
} NODE_t;

NODE_t* head;

void initialize_SLL() {
	head = (NODE_t*)calloc(1, sizeof(NODE_t));
	if (head == NULL) {
		printf("단순 연결 리스트를 생성하지 못했습니다!!\n");
	}
	else {
		printf("단순 연결 리스트 생성을 성공하였습니다.!!\n");
	}
}
void print_node() {
	printf("===================\n");
	NODE_t* p = head;
	while (p->next != NULL) {
		p = p->next;
		printf("이름[%s], 나이[%3d]\n", p->name, p->age);
	}
	printf("===================\n");
}
NODE_t* new_node() {
	NODE_t* data = (NODE_t*)calloc(1, sizeof(NODE_t));
	if (data != NULL) {
		printf("이름을 입력하세요 : ");
		scanf_s("%s", data->name, sizeof(data->name));
		printf("나이를 입력하세요 : ");
		scanf_s("%d", &data->age);
	}
	else {
		printf("메모리 할당 실패!\n");
	}
	printf("새로운 데이터를 생성하였습니다.[%s][%d]\n", data->name, data->age);
	return data;
}
void append_node(NODE_t *data) {
	NODE_t* p = head;
	while (p->next != NULL)
		p = p->next;
	p->next = data;
	printf("새로운 데이터를 추가하였습니다.[%s][%d]\n", data->name, data->age);
}
void insert_node(NODE_t* prev, NODE_t* data) {
	data->next = prev->next;
	prev->next = data;
	printf("새로운 데이터를 삽입하였습니다.[%s][%d]\n", data->name, data->age);
}
void delete_node(NODE_t* data) {
	NODE_t* p = head;
	while (p->next != data) {
		p = p->next;  // data 이전 노드를 반복해서 찾음
	}
	if (p != NULL) {
		p->next = data->next;
		printf("데이터를 삭제하였습니다.[%s][%d]\n", data->name, data->age);
		free(data);
	}
}

<Result>


========================================
순번    이름            나이            전화번호
========================================
[1]     박장군           54             010-1111-1111
[2]     장군봉           34             010-4444-4444
[3]     김공주           23             010-3333-3333
========================================
1 : 데이터 추가
2 : 데이터 삽입
3 : 데이터 삭제
4 : 데이터 검색
0 : 종료
>>

좋은 웹페이지 즐겨찾기