관리 메뉴

JIE0025

[C++] C언어 기본 복습 (const , 메모리공간, malloc, free, call-by-value, call-by-reference ) 본문

기타 학습/Language

[C++] C언어 기본 복습 (const , 메모리공간, malloc, free, call-by-value, call-by-reference )

Kangjieun11 2022. 5. 6. 22:29
728x90

 

const : 상수화

상수 변수는 항상 선언과 동시에 초기화를 해야 한다.  이후에 값 변경  X

 

const를 통한 포인트 변수 선언 >> 포인터변수가 가리키는 대상이 변할 수 없다. 

 

 

 

(( )) 괄호를 통해 좀더 쉽게 이해할 수 있게 했다.

 

1) const int* ptr  = &val1;

 

const (( int * ptr )) 이라고 보자.

- ptr 포인터 변수는 val1의 주소를 가리킴 

- const 선언해서 항상 고정, ptr이 이 가리키는 대상 (*ptr) 에 대한 수정 불가

*ptr = 10 ; //불가능 ptr이 가리키는 대상 수정 불가

val1 = 30;   //가능 가리킴 받는 대상, const 선언 대상이 아님 

 

2) int * const ptr = &val1;

  

 int * const (( ptr )) 이라고 보자.

ptr에 할당된 주소 자체를 변경할 수 없다는 뜻이다. 

 

- const가 변수명 앞에 선언됨  주소값이 상수가 되어 변경될수 없다 

- ptr에 &val1의 주소값 자체를  변경 불가능 >>   *val1의 값은 변경 가능하다. 

ptr = &val2; // 불가능 

*ptr = 40;    //가능

 

3) const int * const ptr3 = &val3 ;   

 

 const (( int * const (( ptr3 ))  ))

 

- ptr은 val3을 가리키며 변경 불가능하다.  ( ptr3  == val3의 주소값 ) 

- val3의 값도 변경 불가능하다. ( val3 = *ptr3 == ptr3이 가리키는 곳의 값 )

- 참조만 가능

 

 

 

 

마지막 복습 

const int num = 10;                       //  변수 num을 상수화 한다. 

const int * ptr1 = &val1 ;               //  포인터ptr1을 이용해 *ptr ( == val) 값을 변경할 수 없다.

int * const ptr2 = &val2 ;               //  포인터 ptr2가 상수화 되어 val2 의 주소값을 고정, 주소자체를 바꿀수 없다. 

const int * const ptr3 = &val3 ;      //  포인터 ptr3은 상수화 되었으며, ptr3을 이용해 val3의 값을 변경할 수 없다. 

 

 


 

메모리공간

메모리 공간은 다음과 같이 구성되어있다. 

 

 

 

 

낮은주소  ------------------------------------------------------------  높은주소

              코드영역   ▶  데이터영역   ▶  힙영역   ▶  스택영역

 

 

1) 코드 영역 (텍스트 영역)

- 실행할 프로그램의 코드 저장 

- CPU가 코드영역에 저장된 명령어를 하나씩 가젹 처리함.

 

2) 데이터 영역 (전역, 정적변수)

- 전역변수, 정적(static)변수가 저장됨

- 프로그램의 시작과 함께 할당, 프로그램 종료시 소멸

 

3) 힙 영역 (사용자 관리)

- 런타임에 따라 크기 결정

- 메모리 공간 동적 할당 및 해제

- 메모리의 낮은 주소부터 높은 주소 방향으로 할당됨.

 

4) 스택 영역 (함수의 호출과 지역변수)

- 컴파일 타임에 따라 크기 결정

- 함수의 호출과 함께 할당, 함수 호출 완료시 소멸

- 스택 영역에 저장되는 함수 호출 정보 : 스택 프레임

- 메모리의 높은주소에서 낮은 주소 방향으로 할당

 

 

 

 

Step 1.
프로그램이 실행되면, 가장 먼저 main() 함수가 호출되어 main() 함수의 스택 프레임이 스택에 저장됩니다.

Step 2.
func1() 함수를 호출하면 해당 함수의 매개변수, 반환 주소값, 지역 변수 등의 스택 프레임이 스택에 저장됩니다.

Step 3.
func2() 함수를 호출하면 해당 함수의 스택 프레임이 추가로 스택에 저장됩니다.

Step 4.
func2() 함수의 모든 작업이 완료되어 반환되면, func2() 함수의 스택 프레임만이 스택에서 제거됩니다.

Step 5.
func1() 함수의 호출이 종료되면, func1() 함수의 스택 프레임이 스택에서 제거됩니다.

Step 6.
main() 함수의 모든 작업이 완료되면, main() 함수의 스택 프레임이 스택에서 제거되면서 프로그램이 종료됩니다.

 

 

출처 : http://www.tcpschool.com/c/c_memory_stackframe

 

 

메모리 동적 할당 : 힙영역에 할당. 

malloc  &  free  할당과 해제

#include <stdlib.h>

void *malloc (size_t size)

 

 

다음은 int형 4개짜리 배열의 값을 int 포인터 변수 p 에 동적 할당하는 코드이다.

#include<stdio.h>
#include<stdlib.h>
 
int main()
{
    int arr[4] = {1,2,3,4};
    int* p; 
    
    // int * 4 만큼의 메모리를 할당
    p = (int *) malloc (sizeof(int) * 4);
    
    if (p == NULL)
    {
        //메모리 할당 실패
        printf("failed");
    }
 
    for (int i = 0; i < 4; ++i)
    {
        p[i] = arr[i];
    }
 
    for (int i = 0; i < 4; ++i)
    {
        printf("%d \n", p[i]);
    }
 
    // 메모리 해제
    free(p);
    return 0;
}

 



call-by-value, call-by-reference

 

1) 값에 의한 호출 ( call-by-value )

 - 값을 복사해 처리

 - 복사에 의해 , 메모리 사용량 증가

 

2) 참조에 의한 호출 ( call-by-reference )

 - 인자로 받은 값의 주소를 직접 참조, 직접적으로 값에 영향을 줄 수 있다. 

 - 원래값이 영향을 받기 때문에 리스크가 있다.