반응형
[ 메모리와 포인터의 사용 ]
#include <stdio.h>
#include <stdlib.h> // malloc, free 함수
int main(){
int *numPtr; // int형 포인터 선언
numPtr = malloc(sizeof(int)); // int의 크기 4바이트만큼 동적 메모리 할당
*numPtr = 10; // ****포인터를 역참조 한뒤 값 할당****
printf("%d\n", *numPtr); // 10 , 포인터를 역참조하여 메모리에 저장된 값 출력
free(numPtr); // 동적 메모리 해제
return 0;
}
- malloc함수에 실제로 값을 저장할 때는 시스템의 한계(RAM, 디스크)이상 저장할 수 없다.
메모리 내용을 한꺼번에 설정하기(memset)
memset함수를 사용하면 메모리의 내용을 원하는 크기만큼 특정값으로 설정할 수 있다.(string.h)
memset(포인터, 설정할값, 크기);
- void *memset(void *_Dst, int _Val, size_t _Size);
- 값 설정이 끝난 포인터를 반환
#include <stdio.h>
#incldue <stdlib.h>
#include <string.h>
int main(){
long long *numPtr = malloc(sizeof(long long)); // long long의 크기 8바이트만큼 동적 메모리 할당
memset(numPtr, 0x27, 8); // numPtr이 가리키는 메모리를 8바이트만큼 0x27로 설정
printf("0x%llx\n", *numPtr); // 0x2727272727272727 : 27이 8개 들어가있음
free(numptr);
return 0;
}
# 실행 결과
0x2727272727272727
먼저
memset
함수를 사용하려면string.h
또는memery.h
헤더파일을 포함해야 한다. 그리고 memset함수에 포인터, 설정할 값, 설정할 크기를 넣으면 된다.memset
함수는 주로 다음과 같이 설정할 값을 0으로 지정하여 메모리의 내용을 모두 0으로 만들 때 주로 사용한다.memset(numPtr, 0, 0); // numPtr이 가리키는 메모리를 8바이트만큼 0으로 설정
> 자료형의 크기와 포인터의 크기
// memset 함수에 설정할 크기를 지정할 때 보통 숫자대신 sizeof를 사용한다.
long long *numPtr = malloc(sizeof(long long));
memset(numPtr, 0, sizeof(long long));
// 여기서 메모리를 sizeof(long long)크기만큼 할당했으므로 설정할 크기도 sizeof(long long)과 같이 지정해야 하며 sizeof(long long *)과 같이 포인터의 크기를 지정하면 안된다! 포인터의 크기는 메모리주소의 크기일뿐 실제 메모리가 차지하는 크기가 아니다. 이부분은 char 포인터에 메모리를 할당해보면 잘 알 수 있을것이다.
char *cPtr = malloc(sizeof(char)); // char의 크기 1바이트만큼 동적 메모리 할당
memset(cPtr, 0, sizeof(char)); // char의 크기 1바이트만큼 0으로 설렁(올바른 방법)
memset(cPtr, 0, sizeof(char *)); // 32비트 : char 포인터의 크기 4바이트만큼 0으로 설정(잘못된 방법)
// 64비트 : char 포인터의 크기 8바이트만큼 0으로 설정(잘못된 방법)
// 할당해줄 크기가 포인터의 크기가 일치한다고 해서 옳은 방법이 아니므로 해당 메모리가 차지하는 크기를 선언해주자.
널포인터
#include <stdio.h>
int main(){
int *numPtr1 = NULL; // 포인터에 NULL 저장
printf("%p\n", numPtr1); // 00000000
return 0;
}
# 실행 결과
00000000
NULL이 들어있는 포인터를 널 포인터라고 하며 아무것도 가리키지 않는 상태를 뜻한다. 따라서 역참조를 할 수 없다.
실무에서는 다음과 같이 포인터가 NULL인지 확인한 뒤 NULL이면 메모리를 할당하는 패턴을 주로 사용한다.
if(ptr = NULL){ // ptr이 널 포인터라면 ptr = malloc(1024); // 1024바이트만큼 메모리 할당 }
포인터에 할당된 메모리를 배열처럼 사용하기
#include <stdio.h>
#include <stdlib.h>
int main(){
int *numPtr = malloc(sizeof(int)*10); // int 10개 크기만큼 동적 메모리 할당
numPtr[0] = 10; // 배열처럼 인덱스로 접근하여 값 할당
numPtr[9] = 20; // 배열처럼 인덱스로 접근하여 값 할당
printf("%d\n", numPtr[0]); // 배열처럼 인덱스로 접근하여 값 출력
printf("%d\n", numPtr[9]); // 배열처럼 인덱스로 접근하여 값 출력
free(numPtr); // 동적 메모리 해제
return 0;
}
# 실행 결과
10
20
int numArr[10]; // int형 요소 10개를 가진 배열 생성
int *numPtr = malloc(sizeof(int) * 10); // int 10개 크기 만큼 메모리 할당
numArr[0] = 10;
numPtr[0] = 10;
free(numPtr);
배열 numArr은 한 번 선언하면 끝이지만 포인터 numPtr은 malloc함수로 메모리를 할당했기 때문에 free함수로 해제해야한다.
*numPtr
처럼 포인터를 역참조한 것과numPtr[0]
처럼인덱스 0에 접근한 것은 같은 값을 가져온다. 그리고numPtr[1]
과*(numPtr+1)
도 같은 값을 가져오는데 후자와 같은 방식을 포인터 연산이라고 한다.
반응형
'프로그래밍 언어 > [ C ]' 카테고리의 다른 글
[ C ] 07. 열거형 (0) | 2020.08.13 |
---|---|
[ C ] 06. 포인터연산 (0) | 2020.08.13 |
[ C ] 04. 포인터의 형변환 (0) | 2020.08.13 |
[ C ] 03. 포인터와 역참조 연산자 (0) | 2020.08.13 |
[ C ] 02. 문자열 관련 자주 쓰이는 함수 (0) | 2020.08.13 |