자료구조

[자료구조 기초] Pointer , 포인터

aliceintr 2021. 4. 13. 08:47
반응형

 

자료구조에서의 핵심 개념인 포인터에 대해 정리해 보자

포인터란?

Variable : 프로그램에서 사용되는 값을 저장하기 위한 컴퓨터 메모리(RAM) 상의 일정 영역

Pointer : 어떤 Variable의 위치를 참조, Variable 의 address 주소 값을 저장 - 빠른 실행이 가능하다.

#include <stdio.h>

void main() {
	int x = 2004;
    printf("%d\n", x);
    int *p;
    p = &x;
    printf("%p\n", p); // pointer의 값은 주소값이다 variable 값이 아님
    printf("%p\n", &x); 
    printf("%d\n", *p); // pointer 가 가르키는 variable 값을 출력
}

이 코드를 도식화하면 아래와 같다.

 

 

p의 값은 x의 주소 값인 200을 가지고 있다.

* operator / 값 연산자 : 포인터 변수가 가리키는 주소에 저장되어 있는 값을 읽어옴

& operator /주소 연산자 : 변수가 차지하는 메모리 영역의 주소를 읽어옴

date = 10; // date 라는 변수에 15 라는 정수의 값을 할당
p = &date; // date 변수가 차지하는 메모리 영역의 주소를 읽어와서 포인터 변수 p에 저장
*p; // 포인터 변수 p가 가르키고 있는 메모리 영역의 값을 읽음
*p = 20; // 포인터 변수 p가 가르키고 있는 메모르 영역에 정수 20을 저장

Memory Allocation

모든 변수는 변수의 타입에 따라 메인 메모리의 필요한 크기의 영역을 할당 받음.

e.g int는 4 bytes ( 32bit)의 메모리 영역을 할 당 받음.

이러한 메모리 영역의 시작 주소가 변수의 주소이다.

포인터 변수도 타입을 가지며, 맞는 타입의 변수를 가리켜야 한다. 즉, 변수가 int 이면 포인터 변수도 int 타입을 가리켜야 함.

변수를 사용하지 않고 프로그램 실행 중에 필요에 따라 메모리를 할당하는 것을 동적 메모리 할당이라 함

how to allocate dynamic memory and deallocate

C와 C++의 동적 메모리 할당 및 해제는 다음과 같다.

  C C++
동적 메모리 할당 p = malloc(sizeof(int)); p = new int;
동적 메모리 해제 free p;
p = NULL;
delete p;

포인터 변수 p는 선언에 의해 정적으로 할당된 메모리 이므로 프로그램이 끝날 때까지 반납되지 않음

포인터 p에 의해서 반납된 메모리에 접근하는 것을 막기 위해, NULL 값을 넣어야 한다.


포인터 변수 선언

int date;
int *p;
*p = 15; // error

위의 코드가 에러가 발생하는 이유는 포인터 p 가 가리키는 변수가 없는데 15라는 값을 넣었기 때문에 오류가 발생한다. 15라는 값을 저장할 주소가 정해져 있지 않기 때문에 에러가 발생한다. 따라서 올바른 표현은 아래와 같다.

int date;
int *p;
p = &date;
*p = 15;


동적 메모리 할당

malloc 함수를 사용하여 메모리의 일정 영역(정수형 데이터를 저장할 수 있는 크기)을 할당하고 그 주소를 변수 p가 가리키도록 함

int date;
int *p;
p = malloc(sizeof(int));
*p = 15;


Dangling Pointer and Garbage

포인터에 의해 생성된 동적 메모리 영역을 반납할 때는 댕글링 포인터와 가비지에 유의해야 함

Dangling Pointer

이미 반납된 영역을 가리키고 있는 포인터, 사용 시에 에러를 발생시킴

int *p, *q;
p = malloc(sizeof(int));
*p = 15;
q=p; // p와 q 는 같은 메모리를 가르침
free(p);
p = NULL; // p의 포인터 해제
*q = 30; //error!!!

Garbage

동적으로 확보한 영역을 가리키던 포인터가 영역을 반납하지 않고 다른 영역을 가리킬 때, 이 영역은 사용하지 못하게 되는 가비지가 됨.

Error overflow, full error 발생

int *p, *q;
p = malloc(sizeof(int));
q = malloc(sizeof(int));
q=p; // p와 q 는 같은 메모리를 가르침

 


Exercise

#include <stdio.h>

void add (int *a){
	*a = *a +10; 
}

void main (void){
	int a = 0;
	add(&a);
	printf("%d",a); // 10 이 출력이 된다. 
};
#include <stdio.h>
#include <malloc.h>

void change_value(int *p, int *q){
	*p = 5;
	*q = 10;
}

void main(){
	int *a, *b;
	a = malloc(sizeof(int)); // 동적 메모리 할당 
	b = malloc(sizeof(int)); // 동적 메모리 할당 
	*a = 10;
	*b = 20;
	change_value(a,b);
	printf("%d, %d", *a, *b); //result : 5,10
    
}
#include <stdio.h>

void swapfake(int *x, int *y){
	int *temp;
	temp = x; 
	x = y;
	y = temp;
}


//Call by Value : 함수 호출 후 에 a, b값은 다시 원래 값으로 변한다. 
void swapreal1(int x, int y){
	int temp;
	temp = x;
	x = y; 
	y = temp;
	printf("the value of a and b in swapreal1 : a = %d b = %d\n\n",x,y);
	//the value of a and b in swapreal1 : a = 20 b = 10
	printf("the address value of a and b in swapreal1 : a = %p b = %p\n\n",&x,&y);
	//the address value of a and b in swapreal1 : a = 0x7ffeabb3187c b = 0x7ffeabb31878
}


//Call by Reference 
void swapreal2(int *x, int *y){
	int temp;
	temp = *x; 
	*x = *y;
	*y = temp;
	printf("the value of a and b in swapreal2 : a = %p b = %p\n\n",x,y);
	//the value of a and b in swapreal2 : a = 0x7ffeabb318a0 b = 0x7ffeabb318a4
	printf("the address value of a and b in swapreal2 : a = %p b = %p\n\n",&x,&y);
	//the address value of a and b in swapreal2 : a = 0x7ffeabb31878 b = 0x7ffeabb31870
	printf("the value of pointer of a and b in swapreal2 : a = %d b = %d\n\n",*x,*y);
	//the value of pointer of a and b in swapreal2 : a = 20 b = 10
	
}

void main(){
	int a = 10, b = 20;
	swapfake(&a, &b);
	printf("%d %d ", a,b);
	//result 10 20
	
	
	printf("Before running swapreal1 : a = %d b = %d\n\n",a,b);
	//Before running swapreal1 : a = 10 b = 20
	printf("the value of a and b in Main : a = %d b = %d\n\n",a,b);
	//the value of a and b in Main : a = 10 b = 20
	printf("the address value of a and b in Main : a = %p b = %p\n\n",&a,&b);
	//the address value of a and b in Main : a = 0x7ffeabb318a0 b = 0x7ffeabb318a4
	swapreal1(a,b);
	printf("After running swapreal1 : a = %d b = %d\n\n",a,b);
	//After running swapreal1 : a = 10 b = 20
	
	
	printf("Before running swapreal2 : a = %d b = %d\n\n",a,b);
	//Before running swapreal2 : a = 10 b = 20
	printf("the value of a and b in Main : a = %d b = %d\n\n",a,b);
	//the value of a and b in Main : a = 10 b = 20
	printf("the address value of a and b in Main : a = %p b = %p\n\n",&a,&b);
	//the address value of a and b in Main : a = 0x7ffeabb318a0 b = 0x7ffeabb318a4
	swapreal2(&a,&b);
	printf("After running swapreal2 : a = %d b = %d\n\n",a,b);
	//After running swapreal2 : a = 20 b = 10
	
}

 

반응형