맞는데 왜 틀릴까..?

Linux

[리눅스] 시스템 프로그래밍 - 메모리 관리

안도일 2022. 12. 9. 20:00

프로세스 구조

 

코드 세그먼트 : 기계어 명령어, 리터럴 상수, 프로그램 코드 및 상수 저장 공간

 

데이터 세그먼트 : 전역 변수, 정적 변수

 

스택 : 실행 시간 스택으로 함수가 호출될 때마다 생성, (지역 변수, 매개 변수, 반환 주소, 반환 값) 등 저장

 

힙 : 동적 메모리 할당 (malloc in C)

 

 

동적 할당

 

 

필요할 때 필요한 만큼만 메모리를 요청해서 사용하여 메모리를 절약한다. 사용한 후 더이상 필요가 없을 경우, 해당 영역을 반납한다.

 

malloc() 은 주소를 반환하는데, 다양한 타입의 메모리 할당이 가능하다. (char, int, double)

따라서 malloc()의 포인터 타입은 void* 이므로 형변환이 필수

 

int* score = (int*)malloc(num*sizeof(int));

 

메모리의 동적 할당은 힙 영역 활용 생성됨. 따라서 운영체제가 자체적으로 해제하지 못함 -> 메모리 누수(system slow) 발생

그렇기 때문에 포인터가 가리키는 메모리를 개발자가 해제 해주어야 한다.

 

free(score)

 

메모리 할당 예

 

40바이트를 할당해보자

 

char *ptr;
ptr = (char*)malloc(40);

int *ptr;
ptr = (int*)malloc(10*sizeof(int));

 

 

구조체를 위한 메모리를 할당해보자

 

struct student{
	int id;
	char name[10];
};

struct student *ptr;
ptr = (struct student*)malloc(n * sizeof(struct student));

 

 

calloc, realloc은 잘 사용하지 않음

 

 

메모리 관리 함수

 

#include <string.h>

void *memset(void *s, int c, size_t n);
//s에서 시작하여 n 바이트 만큼 바이트 c로 설정한 다음에 s를 반환

int memcmp(const void *s1, const void *s2, size_t n);
//s1과 s2에서 첫 n 바이트를 비교해서 메모리 블록 내용이 동일하면 0 return
//s1 < s2 -> 음수 return,  s1 > s2 -> 양수 return

void *memchr(const void *s, int c, size_t n);
//s가 가리키는 메모리의 n 바이트 범위에서 문자 c를 탐색한다.
//c와 일치하는 첫 바이트에 대한 포인터를 return 하거나, c를 찾지 못하면 NULL을 return

void *memmove(void *dst, const void *src, size_t n);
//src에서 dst로 n 바이트를 복사하고, dst를 반환한다.

void *memcpy(void *dst, const void *src, size_t n);
//src에서 dst로 n 바이트를 복사 (두 메모리 영역이 겹치지 않음)

 

메모리 관련 함수는 문자열 처리 함수 (strcpy(), strcmp())와 유사하다.

 

차이점은 문자열 처리함수는 시작 주소만 알려주고 끝은 NULL로 확인하여 길이를 별도로 알려줄 필요가 없지만 메모리 관련 함수는 시작 주소와 함께 작업 대상의 크기(길이) n을 알려주어야 한다.

 

mem.c

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){

    char str[32] = "Do you like Linux?";
    char *ptr, *p;
    
    ptr = (char *)malloc(32);
    memcpy(ptr, str, strlen(str));
    puts(ptr);
    memset(ptr+12, 'l', 1);
    puts(ptr);
    
    p = (char *)memchr(ptr, 'l', 18);
    puts(p);
    memmove(str+12, str+7, 10);
    puts(str);
    
}