자료 구조(Data Structure)
: 데이터의 물리적, 논리적 관계
: 변수 또한 bit와 byte 단위의 Data를 다루는 자료구조지만, 주로 연속적, 규칙적으로 반복되는 Data의 집합을 의미한다.
: 배열과 구조체(+공용체, 열거체)는 사용자 정의 자료형이다.
배열
배열(Array)
연속적, 규칙적으로 반복되는 자료들을 다루는 가장 기본적인 자료구조
배열 a 의 자료형(Data Type)은 int[5] 와 같은 사용자 정의 자료형(User-Defined Data Type)이다.
배열과 포인터(Array & Pointer)
다차원 배열(Multidimensional Array)
: 배열을 요소로하는 배열
배열과 동적할당(Dynamic Memory Allocation)
03. memory
03.1. 개념
대표사진 삭제
사진 설명을 입력하세요.
03.1.1. 코드(Code) 영역
메모리의 코드(Code) 영역은 실행할 프로그램의 코드가 저장되는 영역으로 텍스트 영역이라고도 부른다. Hex파일이나 BIN 파일 메모리이다. CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리하게 되며 컴파일 타임에 결정되고 중간에 코드를 바꿀 수 없게 Read-Only로 지정되어 있다.
03.1.2. 데이터(Data) 영역
메모리의 데이터(Data) 영역은 프로그램의 전역 변수(global), 정적(static) 변수, 배열(array), 구조체(structure)가 저장되는 영역이다. 초기화된 데이터는 data영역에 저장되며, 초기화되지 않는 데이터는 BSS(Block Stated Symbol) 영역에 저장된다. 이 영역은 실행 도중에 전역 변수가 변경될 수도 있으니 Read-Write로 지정되어 있다. 프로그램의 시작과 함께 할당되고, 프로그램 종료 시 소멸된다.
03.1.3. 힙(Heap) 영역
메모리의 힙(Heap) 영역은 사용자가 집접 관리할 수 있는 '그기고 해야만 하는' 메모리 영역으로 사용자에 의해 메모리 공간이 동적으로 할당되고 해제된다. 힙 영역은 메모리의 낮은 주소에서 높은 주소의 방향으로 할당된다.
03.1.4. 스택(Stack) 영역
메모리의 스택(Stack) 영역은 함수의 호출과 관계되는 지역 변수와 매개변수가 저장되는 영역으로 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸된다. 이렇게 스택영역에 저장되는 함수의 호출 정보를 스택 프레임이라고 한다. 스택 영역은 푸시(push) 동작으로 데이터를 저장하고 , 팝(pop) 동작으로 데이터를 인출한다. 이러한 스택은 후입선출(LIFO, Last-In First-Out) 방식에 따라 동작하므로, 가장 늦게 저장된 데이터가 가장 먼저 인출된다. 스택 영역은 메모리의 높은 주소에서 낮은 주소의 방향으로 할당된다.
대표사진 삭제
사진 설명을 입력하세요.
03.2. 개념
- 메모리 할당, 해제 함수는 stdlib.h 헤더 파일에 선언되어 있다.
- Byte 단위로 지정한다.
// 4 GiB ≒ 4294967296 Byte
numPtr = malloc(sizeof(int) * 1024 * 1024 * 1024);
- error : "error C2440: '=': 'void *'에서 'int *'(으)로 변환할 수 없습니다."
>> 파일 확장자가 .cpp (C++ 컴파일러)의 경우
- 동적 메모리 할당(dynamic memory allocation)
- 변수는 스택(stack)에 생성, malloc 함수는 힙(heap) 부분의 메모리를 사용한다.
- 스택과 힙의 큰 차이점은 메모리 해제. 힙에서 할당한 메모리 해제는 선택이 아닌 필수다.
- 메모리 누수(memory leak)
03.3. malloc
#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
int main()
{
int *numPtr; // int형 포인터 선언
numPtr = malloc(sizeof(int)); // int의 크기 4바이트만큼 동적 메모리 할당
*numPtr = 10; // 포인터를 역참조한 뒤 값 할당
printf("%d\n", *numPtr); // 10: 포인터를 역참조하여 메모리에 저장된 값 출력
free(numPtr); // 동적 메모리 해제
return 0;
}
03.4. memset
#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
#include <string.h> // memset 함수가 선언된 헤더 파일
int main()
{
long long *numPtr = malloc(sizeof(long long)); // long long의 크기 8바이트만큼 동적 메모리 할당
memset(numPtr, 0x27, 8); // numPtr이 가리키는 메모리를 8바이트만큼 0x27로 설정
printf("0x%llx\n", *numPtr); // 0x2727272727272727: 27이 8개 들어가 있음
free(numPtr); // 동적으로 할당한 메모리 해제
return 0;
}
03.5. null Pointer
#include <stdio.h>
int main()
{
int *numPtr1 = NULL; // 포인터에 NULL 저장
printf("%p\n", numPtr1); // 00000000
return 0;
}
if (ptr == NULL) // ptr이 널 포인터라면
{
ptr = malloc(1024); // 1024바이트만큼 메모리 할당
}