[C] 동적 메모리 할당 ( Dynamic Memory Allocation )
C - 동적 메모리 할당 ( Dynamic Memory Allocation )
1. 프로세스의 메모리 구조
2. malloc(), calloc(), realloc(), free()
1. 프로세스의 메모리 구조
프로그램이 실행되어 메모리에 올라가면 프로세스가될텐데, 이때 프로그램은 다음과 같은 구조로 메모리에 올라간다.
Text section
Text 영역 또는 Code 영역이라고하는 이 영역은 프로그램의 소스코드가 올라가는 영역이다. 이 영역은 'read only'인데 그 이유는 프로그램 코드 변조를 예방하기 위해서이다.
Data section
초기화된 전역변수나 static변수가 저장되는 영역이다.
BSS
초기화되지않은 전역변수나 static변수가 저장되는 영역이다. 물론 전역변수에 명시적으로 값을 대입시켜 초기화시켜주지 않아도 컴파일러가 자동으로 0으로 초기화해주지만 어쨋거나 대입연산자를 통해 명시적으로 초기화시켜준게 아니라면 BSS 영역에 저장된다.( 전역변수의 초기화여부에 따라 저장영역을 나눠논 이유는 잘모르겠다. )
Heap
동적으로 변수를 메모리에 할당할 때 이 영역에 저장된다.
Stack
지역변수나, 매개변수, 함수가 호출되고 리턴되고와 같은 행동이 이 영역에서 일어난다.
2. malloc(), calloc(), realloc(), free()
malloc()함수의 반환타입은 void이기 때문에 잊지말고 타입캐스팅을 해야한다.
#include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int n, i, *ptr, sum=0; printf("Enter number of size: "); scanf("%d", &n); ptr = (int*)malloc(n * sizeof(int)); if (ptr == NULL) { printf("Error: Memory not allocated"); exit(0); } printf("Enter elements: "); for ( i=0; i<n; i++) { scanf("%d", ptr + i); sum += *(ptr + i); } printf("%d", sum); free(ptr); return 0; }
calloc()함수는 malloc()함수와 같은데 추가적으로 할당받은 메모리 안의 값을 0으로 초기화한다.
calloc()함수의 내부구현을 보면 malloc()함수를 이용해 동적으로 메모리를 할당받고, 할당받은 주소값에 0으로 덮어씌운다.
다음 예제는 calloc()함수의 구현소스코드이다.
#include "ancidecl.h" #include <stddef.h> /* For systems with larger pointers than ints, this must be declared. */ PTR malloc (size_t); void bzero (PTR, size_t); PTR calloc (size_t nelem, size_t elsize) { register PTR ptr; if (nelem == 0 || elsize == 0) nelem = elsize = 1; ptr = malloc (nelem * elsize); if (ptr) bzero (ptr, nelem * elsize); return ptr; }
realloc()함수는 malloc()함수를 통해 동적으로 할당받은 메모리의 공간의 크기를 다시 조정해주는 함수다.
Usage of realloc(): void* realloc(void *ptr, size_t size);
#include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int *buffer; /* get a initial memory block */ buffer = (int*)malloc(10 * sizeof(int)); if (buffer == NULL) { puts("Error: Failed allocate memory"); exit(0); } /* get more memory with realloc */ buffer = (int*)realloc(buffer, 20 * sizeof(int)); if (buffer == NULL) { puts("Error: Failed allocate memory"); exit(0); } free(buffer); return 0; }
'Programming > C C++' 카테고리의 다른 글
[C++ 문법] 'const' 위치에 따른 멤버함수의 의미 (2) | 2019.05.15 |
---|---|
[C] 네트워크 인터페이스에 관한 정보 - ioctl() (0) | 2019.02.02 |
[C] Reserved Names (0) | 2019.01.31 |
[C] C 프로그램의 컴파일 과정 (0) | 2019.01.30 |
[C] File I/O (0) | 2019.01.10 |
댓글
이 글 공유하기
다른 글
-
[C] 네트워크 인터페이스에 관한 정보 - ioctl()
[C] 네트워크 인터페이스에 관한 정보 - ioctl()
2019.02.02네트워크 인터페이스에 관한 정보를 알고 싶다면 ioctl() 시스템콜을 사용할 수 있습니다. 전형적인 운영체제는 2계층으로 나뉩니다. User Space(사용자 모드)와 Kenel Space(커널 모드). User Space에 상주하는 애플리케이션이 Kenel Space에 존재하는 자원을 사용하고자할 땐 시스템콜을 이용합니다. 참고로, System Call Function은 내부적으로 System Call Vector와 대응됩니다. 예를들면, exit()함수는 System Call Vector Number: 1번 write()함수는 System Call Vector Number: 4번. 전형적인 운영체제의 커널은 수 백개의 System Call Vector를 제공합니다. ioctl() 시스템콜은 디바이스… -
[C] Reserved Names
[C] Reserved Names
2019.01.31Reserved Names C언어는 클래스 단위가 아니고, 전역변수나 함수들이 존재하기 때문에 엄격한 이름 규칙(Naming Convention)이 필요하다.다음과 같은 상황을 가정해보자 1. 여러 헤더파일을 포함시킬텐데, 포함시킨 헤더파일들에서 함수명 || 매크로명 || 전역변수명이 중복 선언되었다면? 2. 포함시킨 헤더파일과 내 소스코드에서 함수명 || 매크로명 || 전역변수명이 중복되었다면? 이를 방지하기위한 규칙 1. __(Double Underscroe), A_(대문자+Underscore)는 예약된 이름으로 사용한다. 2. is || to로 시작하는 이름은 테스트를 하거나 변환하기위한 용도로 사용한다. 3. LC_로 시작하는 이름은 추가적인 로컬 매크로 정의를 위해 사용한다. 4. SIG로 시작… -
[C] C 프로그램의 컴파일 과정
[C] C 프로그램의 컴파일 과정
2019.01.30C 프로그램의 컴파일 과정 C 소스코드를 짠 후 컴파일을 하게되면 다음과 같은 4가지 일이 일어난다. 1. 전처리 ( Preprocessor ) 2. 컴파일 ( Compilation ) 3. 어셈블리 ( Assembly ) 4. 링킹 ( Linking ) 컴파일 과정을 테스트해보기 위해 간단한 test.c 프로그램을 작성한다. #include // Comment #define STRING "Test String" #define COUNT (5) int main() { int i; for (i=0; i test.txt 다음으로 2번째(컴파일) 과정을 진행한 후의 결과를 확인하기 위해선 gcc -S 옵션을 사용한다. gcc -S test.c gcc -S 옵션을 주어 컴파일을 하게되면 'test.s' 라는 어… -
[C] File I/O
[C] File I/O
2019.01.10C - File I/O 1. File open + read || write + close 2. Reading and Writing strings to a file 3. Reading and Writing binary to a file 들어가기에 앞서File I/O 함수들을 이해하기 위해선 컴퓨터의 입/출력에 대한 이해가 기반이 되야한다.입/출력에 대한 모든 내용을 그림으로 살펴보면 아래와 같다. 스트림(Stream)?입/출력을 배우면 항상 나오는 개념이 바로 스트림이다. 표준 입/출력 장치를 예로들면, 키보드와 모니터는 각각 독립된 장치인데 어떻게 키보드에서 입력을 받은 데이터를 모니터로 출력해줄 수 있는 걸까? 바로 스트림이 둘 사이를 연결시켜놓아기 때문이다. 정확히 말하면 키보드에서 입력받은 데이터는…
댓글을 사용할 수 없습니다.