반응형

1. 동적 메모리 할당


지금까지는 배열을 선언 할 때 동적 메모리 할당을 다음과 같이 했다.


int arr[200];


하지만 자신이 필요한 만큼만 그때그때 배열 크기를 정해주기 위해서는 어떻게 해야할까??


방법은 다음과 같다.


타입 *변수명 = (타입*)malloc(sizeof(int) * 배열크기);

int *arr = (int*)malloc(sizeof(int) * 200);


다음 코드를 직접 작성해보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <malloc.h>
 
 
int main()
{
    int n;
    scanf("%d"&n);
 
    int *arr;
    arr = (int *)malloc(sizeof(int* n);
 
    printf("%d\n"sizeof(arr));
 
    arr[1= 1;
    arr[199= 2;
 
    printf("%d %d", arr[1], arr[199]);
 
    free(arr);
 
    return 0;
}
 

//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


그리고 실행시켜 20을 입력해보고, 200을 입력해보자.


출력은 4또는 8 그리고 1과 2가 출력되어야 한다. 이때 오류가 있는지도 확인해보자.


첫번째로 sizeof() 함수는 크기를 가져와주는 함수이다.


sizeof(arr)을 한다면 arr 포인터의 크기를 가져와주는 함수가 된다.


이때 4또는 8의 의미는 운영체제 비트에 따라 다르게 나타나는데


int형이 보통 4byte로 지정되어있지만, 64비트에서는 8byte로 나타나기도 하고 4byte로 나타나기도 한다.


이는 운영체제 환경 차이이다.



** 왜 배열 크기가 200인데 4또는 8이 뜨나요?


지금 우리는 malloc를 통해 메모리 할당을 받은 상태지만 여전히 포인터 arr은 포인터 자체를 나타내고 있기에 sizeof(arr)은 포인터 크기를 따르게 된다.


** free는 뭔가요?


malloc를 통해 메모리를 할당해줬다면 메모리를 free를 통해 지워줘야 한다.


그렇지 않으면 메모리 누수(memory leak)가 발생하여 프로그램이 커질수록 메모리 공간이 없어지게 되고 결국 프로그램이 터지게 된다.


문제 1.

위의 코드에서 n = 20일때 이상한점이 있는지 찾아보자.




문제 2.


struct를 구성하고 동적 메모리 할당을 통해 struct 크기를 20개로 구성해 보자.

struct의 구성은 다음과 같다.

int a;

char b;

int c;



메모리 할당에 관해서는 자료구조를 공부 할 때 좀 더 깊게 배울 수 있으니 지금은 여기까지 알아두도록 하자.




2. 비트 연산


지금 당장 하지 않아도 된다.


괜히 흥미를 잃고 싶지 않다면 넘기자.



사실 우리가 배우는 모든 값들은 컴퓨터 내부에서 비트로 저장 되고 있다.


우리 눈에만 가시적으로 100이 100으로 보이지 컴퓨터는 이를 0000 0000 0110 0100으로 보고있다.


왜 비트연산을 배우는가?


1. 컴퓨터에 좀 더 근접한 연산을 할 수 있게 된다.


a + 1이라는 명령을 컴퓨터에게 보내면 컴퓨터는 저 내용을 자신만의 기계어로 변환시켜 + 1을 해주는 과정을 펼친다.


하지만 그냥 비트연산으로 바로 명령을 보내면 컴퓨터는 기계어로 변환시키는 과정없이 바로 비트 연산을 해버린다.


예를들어보자.


숫자 2는 비트로 0010이다.


2 << 1라는 의미는 숫자 2를 나타내는 비트를 왼쪽으로 한칸 쉬프트 하라는 의미이다.


따라서 0010에서 0100으로 된다.


이는 4를 의미한다.


우리가 2*2로하지 않고 2 << 1로 4를 나타낸것을 방금 보았듯이 비트 연산을 알면 컴퓨터와 더 친해질 수 있고 프로그램 속도도 더 빠르게 낼 수 있게 된다.


이제 다양한 비트 연산을 한번 알아보자.


& 연산(and 연산)

두 비트의 같은 위치가 1이면 1 반환, 그 외에는 모두 0을 반환한다.


  0101

&0011

-------

  0001


문제 1.

5 & 3은 무슨 값을 의미하는지 알아보자.

답 :: 1


| 연산(or 연산)

두 비트의 같은 위치중 하나라도 1이면 1 반환, 그 외에는 모두 0을 반환한다.


  0101

| 0011

-------

  0111


문제 1.

5 | 3은 무슨 값을 의미하는지 알아보자.

답 :: 7


^(xor 연산)

두 비트의 같은 위치가 서로 다른 수이면(하나는 0, 하나는 1) 1 반환 그 외에는 0 반환


  0101

^0011

-------

  0110


문제 1.

5 ^ 3은 무슨 값을 의미하는지 알아보자.

답 :: 6



<< (left shift) 연산

해당하는 비트를 왼쪽으로 n칸 밀어준다. ( 주의 :: *2가 절대 아니다. )


1 << 2 

0001을 왼쪽으로 2칸 민다.

0100 = 4


1 << 10

0001을 왼쪽으로 10칸 민다.

0100 0000 0000 = 1024


문제 1.

1<<k의 의미는 무엇을 의미할까?



>> (right shift) 연산

해당하는 비트를 오른쪽으로 n칸 밀어준다. ( 주의 :: /2가 절대 아니다. )


1 >> 2

0001을 오른쪽으로 2칸 민다.

0000 = 0


여기서 파악 할 수 있는 것은 비트의 끝지점에서 밀리게 되면 해당하는 비트 값이 사라지게 된다.


추가적인 비트 연산 및 응용 :: http://www.crocus.co.kr/592





3. 메모리 구조


매번 메모리 / 주소 등등 이야기를 해왔는데 그렇게 말한 메모리가 뭔지 간단히 알아보자.




하나의 프로그램이 형성되면 OS가 메모리를 할당해주는데 메모리는 CODE, DATA(BSS), HEAP, STACK로 나뉘어져 있다.


오른쪽 코드의 1~6을 보자.


1. 말그대로 CODE 부분은 코드 전체를 저장하기 위한 공간을 말하고 있다.


2. DATA부분은 우리가 아직 배우지 않은 전역변수라는 변수값들을 가지고 있게 된다.


저 부분에서는 전역변수가 0으로 자동으로 초기화 된다.


예를들어 int a[100]은 0~99번까지 모두 0으로 초기화 되어있지만 int main속에 만약 int a[100]이 있었다면


모두 0으로 초기화 되어있지 않고 쓰레기 값(알수없는 값)이 들어가있게 된다.


3. HEAP 부분은 우리가 최근에 배운 malloc처럼 메모리를 실행 도중에 할당해준 값들을 저장하는 곳이다.


따라서 HEAP 부분은 런타임 시간에 결정한다고 한다.(즉, 실행되는 도중에 HEAP 부분이 계속 변경된다.)


4. STACK 부분은 다양한 지역변수들 및 함수들이 들어가는 부분이다.


이 부분은 컴파일 시간에 결정한다고 한다.(즉, 프로그램을 빌드하고 실행시키는 과정에서 결정되는 것이다.)








정리하는 시간

http://ychooni.tistory.com/63?category=278498




반응형

'Tutoring > C' 카테고리의 다른 글

형 변환, typedef, 헤더파일 소개  (0) 2018.02.26
매크로 함수, 파일 입출력  (0) 2018.02.26
구조체, 함수, 포인터  (0) 2018.02.26
연산자, 조건문, 반복문, 배열  (0) 2018.02.22
변수 선언, 입/출력, 연산, 주석  (0) 2018.02.22