#include<stdlib.h>
 
void* malloc(size_t size) //malloc 함수의 원형.
void* calloc(size_t elt_count, size_t elt_size) //calloc 함수의 원형.
↓↓↓↓↓↓↓↓↓↓
int *arr = (int*)calloc(size, sizeof(int));
int *arr = (int*)malloc(size*sizeof(int)); //둘 다 같은 결과.
 
 free함수
#include<stdlib.h>
 
void free(void* ptr) //free 함수의 원형.
- Heap 영역은 컴퓨터가 알아서 올리고 내리고 해주지 않는다. 그래서 메모리를 할당하는 것과
더불어 할당된 메모리를 해제하는 것도 프로그래머가 직접해 주어야 한다.
free함수로 힙영역의 메모리를 해주지 않으면 쌓이고쌓여서 메모리 부족현상이 일어나게 된다.
 
#include<stdio.h>
#include<stdlib.h>
 
int main(void)
{
       int size, i;
       int *arr;
 
       fputs("Input number!! to memory allocate: ", stdout);
       scanf("%d", &size);
 
       arr = (int*)calloc(size, sizeof(int));
       //arr = (int*)malloc(size*sizeof(int)); //위의 것과 같다.
       if(arr == NULL)
       {
              puts("Meomory allocation filed\n");
              exit(1); //비 정상적 종료를 의미.
       }
 
       for(i=0; i<size; i++)
              scanf("%d", &arr[i]);
 
      for(i=0; i<size; i++)
              printf("%d ", arr[i]);
 
       free(arr);
 
       return 0;
}


Stack Area = 지역변수, 매개변수가 올라가는 메모리 지역. (정적으로 할당)
- 함수호출이 끝나면 메모리상에서 없어짐.
 
Data Area = 전역변수, static변수가 올라가는 메모리 직역. (정적으로 할당)
- 프로그램이 종료되어야 메모리상에서 사라짐.
 
Heap Area = 프로그래머 할당 메모리 지역. (동적으로 할당)
- 데이터 영역이나 스택과 달리 프로그래머에 의해 필요한 만큼 메모리를 할당하고 해제할 수 있다.
 
※ Stack, Data 영역은 컴파일-타임에서 할당될 메모리의 크기가 결정되어야 한다.
※ Heap 영역은 런-타임에서 할당될 메모리의 크기가 결정되어야 한다.
break, return, exit(0 or 1)
break문은 반복문이나 제어문등을 종료할 때 쓰인다.
return문은 함수를 종료할 때 쓰인다.
exit문은 프로그램을 완전히 종료할 때 쓰인다. exit(1)이면 오류로 인해 프로그램 완전종료를 알린다.
break < return < exit 순으로 exit가 가장 크다.
return이 만약 void function(void)에 쓰이면 해당 함수만 종료하고 main함수로 돌아간다.
exit이 만약 void function(void)에 쓰이면 main함수가 아니라 다른 함수에 있더라도 프로그램을 완전 종료해 버린다.

Posted by scii
:

내가 필요로하는 것이 존재하지 않을 때 다음 두 가지 방법중 하나를 선택해야 한다.

1. 처음부터 새로 만든다.

2. 기존의 것을 활용해서 만든다.

상황에 따라 좋은 선택은 달라지기 마련이다. 마땅히 활용할 대상이 없거나 활용의 결과가 만족스럽지 못하다면 처음부터 새로 만들어야겠지만, 그렇지 않은 경우라면 기존의 것을 활용하는게 훨씬 합리적인 판단일 수 있다.



원형 연결 리스트의 구현결과인 CLinkedList.h와 CLinkedList.c 를 변경하지 않고 그저 활용만으로 스택을 구현하였다.

CLinkedList.c

CLinkedList.h



Posted by scii
:

기능적인 부분만 고려를 한다면 배열은 대부분 연결 리스트로 교체가 가능하다. 배열도 연결 리스트도 기본적인 선형 자료구조이기 때문이다.


head -> data1 -> data2 -> data3 -> NULL


이렇게 메모리 구조만 놓고 보면 이것이 스택을 구현한 것인지, 단순 연결 리스트를 구현한 것인지 알 수 없다.

다만 위의 메모리 구조를 바탕으로 push 연산과 pop 연산이 포함된 ADT를 갖는다면 이것이 스택이 되는 것이다.



Posted by scii
:

스택이란 '쟁반 위에 쌓인 접시', '쌓아 올려진 상자더미' 를 연상할 수 있겠다.

즉, 맨 밑에 상자(제일 먼저 들어간 데이터) 를 꺼내려면 위에 얹혀있는 상자들부터 꺼내야 꺼낼 수 있다. 이것이 바로 스택의 특성이다.

스택은 나중에 들어간 것이 먼저 나오는 구조이다 보니 '후입선출방식의 자료구조' 라고도 불리고, 영어로 'LIFO(Last-In, Fisrt-Out) 구조의 자료구조' 라고도 불린다.

실제로 스택은 쉽게 이해할 수 있고 또 숩게 구현할 수 있는 자료구조이다.


스택을 대표하는 넣고, 꺼내고, 들여다 보는 연산을 가리켜 각각 push, pop, peek 라고 한다.


void StackInit(Stack * pstack); 

- 스택의 초기화를 진행한다.

- 스택 생성 후 제일 먼저 호출되어야 하는 함수이다.

int IsEmpty(Stack * pstack);

- 스택이 빈 경우 TRUE(1)을 그렇지 않은 경우 FALSE(0)을 반환

void Push(Stack * pstack, Data data);

- 스택에 데이터를 저장한다. 매개변수 data로 전달된 값을 저장

Data Pop(Stack * pstack);

- 마지막에 저장된 요소를 삭제

- 삭제된 데이터는 반환된다.

- 본 함수의 호출을 위해서는 데이터가 하나 이상 존재함이 보장되어야 한다.

Data Peek(Stack * pstack);

- 마지막에 저장된 요소를 반환하되 삭제하지 않는다.

- 본 함수의 호출을 위해서는 데이터가 하나 이상 존재함이 보장되어야 한다.



실행결과에서 입력된 데이터가 역순으로 출력됨을 보이고 있다. 

그리고 이것이 스택의 가장 중요한 특성이다.


Posted by scii
:

MyFunc라는 함수를 호출했는데, 그 안에서 throw절이 실행되면서 예외가 발생했다. 그런데 이 함수내에는 예외처리를 위한 try~catch 문이 존재하지 않는다.

그렇다면 이 상황에서 발생한 예외는 어떻게 처리될까?


-> 이러한 경우 예외처리에 대한 책임은 MyFunc를 호출한 영역으로 넘어가게 된다.



위 예제의 divide 함수 내에서는, 매개변수 num2의 값이 0인 경우 예외가 발생하는데, 이 위치를 감싸는 try~catch 문은 존재하지 않는다. 이런 경우 Divide 함수를 호출한 21행의 위치로 예외 데이터가 전달된다. 

물론 예외 데이터가 전달되었으니, 예외처리에 대한 책임도 함께 넘어간다. 따라서 21행을 감싸는 try~catch문에 의해서 예외가 처리된다. 


결론 : 예외가 처리되지 않으면, 예외가 발생한 함수를 호출한 영역으로 예외 데이터가(더불어 예외처리에 대한 책임까지) 전달된다.






예외상황이 발생한 위치와 예외상황을 처리해야 하는 위치가 다른경우의 예제.



예외의 발생과 처리에 대한 가장 일반적인 모델을 보여준다.


이 예제로 알 수 있는 점: 함수 내에서 함수를 호출한 영역으로 예외 데이터를 전달하면, 해당 함수는 더 이상 실행되지 않고 종료가 된다.

즉, 함수 내에서 예외 데이터를 전달하면, return 문의 실행을 통한 함수의 종료와 마찬가지로 함수를 완전히 빠져 나오는 꼴이 된다.






스택 풀기(Stack Unwinding)


- 예외가 처리되지 않아서, 함수를 호출한 영역으로 예외 데이터가 전달되는 현상을 가리켜 '스택 풀기' 라고 한다.



위 예제는 예외가 발생할 수밖에 없다. 함수 호출 순서는 이렇다.

main -> one -> two -> thr


그리고 thr함수에선 무조건 예외를 발생시킨다. 그런데 이 예외를 처리하기 위한 try~catch 문이 main 함수에 정의되어 있어서 main으로 예외 데이터가 전달된다. 


이렇듯 예외가 처리될 때까지, 호출된 함수의 역순으로 예외 데이터가 전달된다. 그리하여 결국 예외는 thr함수에서 발생했지만, 예외의 처리는 main 함수에서 이뤄지는 형태가 된다.

그런데 예외 데이터가 전달되면, 예외 데이터를 전달한 함수는 종료되기 때문에, 예외 데이터를 전달한 함수의 스택이 반환되는 것은 당연하다. 그래서 예외 데이터의 전달을 가리켜 '스택 풀기(스택의 반환)'라고 하는 것이다. 


※ 만약 main 함수에 try~catch 문을 삭제하면... 즉, 예외상황이 발생했는데 이를 처리하지 않으면 어떻게 될까?

- 예외가 처리되지 않아서, 예외 데이터가 main 함수에까지 도달했는데, main 함수에서조차 예외를 처리하지 않으면, terminate 함수(프로그램을 종료시키는 함수) 가 호출되면서 프로그램이 종료되어 버린다.


'Programming > C++' 카테고리의 다른 글

예외상황을 표현하는 예외클래스의 설계  (0) 2012.10.24
하나의 try 블록과 다수의 catch 블록  (0) 2012.10.24
예외처리(Exception Handling)  (0) 2012.10.17
템플릿과 static  (0) 2012.10.17
템플릿 인자  (0) 2012.10.16
Posted by scii
: