c언어에서 포인터와 배열 + 메모리구조

박경현·2023년 6월 18일
0
post-thumbnail

C언어 입문 책을 20살때 보고 다시 보게 될 줄은...
포인터와 메모리 구조 쪽은 정리를 하고 가는게 낫다고 생각해서 이번에 적어 보려고 한다!

아마 구조체랑 파일 관련까지는 C언어 기본 부분을 다 적을거 같다

포인터

기계어에서는 변수 이름보다 변수가 위치한 메모리 주소가 더 중요하다!!
주소만 알고 있다면 변수 값 읽고 바꾸기가 가능!!

메모리와 운영체제의 관계 -> 이거 아래서 자세히 보지만 여기서 맛보기로!

운영체제는 메모리 주소를 1바이트 단위로 관리!
우리가 배우는 C언어에서 변수에 값을 넣는 것 -> 직접 주소 지정방식 int a = 5;
하지만 직접 주소 지정 방식은 값을 주고 받기 때문에 서로 다른 함수에 존재하는 변수를 참조하지 못한다

그래서 포인터 즉 간접 지정방식이 나왔다
ex) 주소가 적힌 쪽지는 102번 사물함에 있다(사물함이라는 매개체를 이용해 주소를 간접 지정!)

short birthday; 
short *ptr;
ptr = &birthday; // &birthday는 birthday의 주소!
printf(“birthday 변수 주소는 %p 입니다.\n”, ptr);

포인터와 배열의 상관관계

이건 말보다 코드가 더 빠르게 이해가 가능하다!

char data[5]; 
data[1]=5;
*(data+1) = 5 //data[1]=5; 와 같은 뜻!
// *data는 data[0]의 주소를 의미!

int tips = 0x12345678, sum;
chat *p;
p = (char*)&tips;
sum = *(p+0)+ *(p+1)+ *(p+2)+ *(p+3);
// sum = p[0] + p[1] + p[2] + p[3]; 과 같음!

즉 포인터 변수를 이용해서 배열의 값을 불러올 수 있다!!
반복도 가능!!

char data[5] = {1,2,3,4,5};
int i, sum =0, select=2;
chat *p = data+ select; 
// data는 data배열의 시작주소  +2  => &data[2]
for(int i =0; i<10; i++) sum = sum + *p;

메모리 할당 => 이게 중요!

컴퓨터 메모리는 OS가 관리한다!
C언어로 작성한 소스(.c)파일은 컴파일 작업과 링크 작업을 거쳐서 기계어로 이루어진 실행파일(.exe)가 됨
실행 파일에 있는 명령들을 cpu가 직접 실행하는 것이 아니라 먼저 명령 들 모아서 메모리 재구성 => 프로세스
메모리에 프로세스가 구성되면 이제서야 cpu가 명령들을 실행 가능!! => 그래서 실행중인 프로그램이 프로세스이다!

프로세스는 단순 실행 명령만 모아둔게 아님!!
여러가지 정보나 사용자가 입력한 데이터를 기억하는 메모리 공간도 포함됨!
세그먼트 라고 함!! 프로세스는 세그먼트의 집합으로 구성되며
코드 세그먼트, 데이터 세그먼트 스택 세그먼트는 각각 한개 이상의 세그먼트로 구성!

코드 세그먼트 -> 기계어의 명령들은 프로세스의 코드 세그먼트에 복사되어 프로그램 실행에 사용!!

데이터 세그먼트 -> 프로그램이 시작해서 끝날때까지 사용되는 데이터 보관, 정적 전역 static 등

스택세그먼트 -> 함수 등에서 사용하는 임시데이터 (지역변수 매게변수 리턴값 등)

데이터 세그먼트에 해당 변수를 저장할 메모리 영역 배정 -> 정적 메모리 할당(static Memory Allocation)

-> 즉 메모리 크기 못 바꿈

stack -> 두개의 포인터로 많은 양의 데이터를 효과적으로 관리하는 이론!

BP(베이스 포인터)를 기준으로 데이터 추가될때마다 sp(스택포인터)가 위에를 가리킴
스택에 데이터 추가시 -> SP는 4바이트만큼 증가!
간단하게 지역 변수가 사용되면 넣고 끝나면 뺌!!

동적메모리 할당 -> 힙은 malloc(memory allocation)을 사용해서 메모리 할당!

void malloc(size_t size); // size_t는 양수만 가능! 메모리 크기는 당연히 양수만 void p = malloc(100);
// 100바이트 메모리를 할당하여 포인터 p에 저장

void를 사용하면 형변환 해줘야함!
short
p = (short *) malloc(100); // 이러면 그룹으로 묶어 관리 가능
차고로 stack은 자동 메모리 해제이지만 heap은 free를 사용해서 직접 메모리 해제해야함!!

// sizeof를 사용해서 메모리 사용 단위까지 적어줘버리자!
// 메모리를 4바이트로 나눠서 할당하겠다고 좀더 직관적 파악 가능!
int p = (int )malloc(sizeof(int) 3); // 4 3 =12 바이트를 할당함!

profile
SW로 문제를 해결하려는 열정만 있는 대학생

0개의 댓글