따라 배우는 C언어 : 13
🙇♀️13
🪐메모리 레이아웃 훑어보기
- 명령줄 인수와 환경 변수들 Command-line arguments and environment variables
- 스택 Stack (크기 변함)
- 자유 공간 Free
- 힙 Heap (크기 변함)
- 초기화되지 않은 전역/정적 변수들 BSS(Block Started by Symbol) Segment (크기 고정)
- 초기화된 전역/정적 변수들 DATA Segment (크기 고정)
- 프로그램 코드 TEXT Segment (크기 고정)
🪐객체와 식별자, lvalue와 rvalue
객체 : Object
식별자 : Identifier
L-value : left side of an assignment
R-value : right side, variable, constant, expressions
🪐난수 생성기 모듈 만들기 예제
// my_rand.c
static unsigned int next = 1;
int my_rand()
{
next = next * 1103515245 + 1234;
next = (unsigned int)(next / 65536) % 32768;
return (int)next;
}
void my_srand(unsigned int seed)
{
next = seed;
}
// my_rand.h
#pragma once
int my_rand();
void my_srand(unsigned int seed);
🪐메모리 동적 할당
int n = 0;
// n from files, internet, scanf, etc.
char* arr = (char*)malloc(sizeof(char) * n);
// ...
free(arr);
float x;
char str[] = "Dancing with a Star";
int arr[100];
/*
malloc() returns a void type pointer.
void* : generic pointer
free() deallocates the memory
*/
double* ptr = NULL;
ptr = (double*)malloc(30 * sizeof(double));
if (ptr == NULL)
{
puts("Memory allcation failed.");
/*
exit(EXIT_FALURE) is similar to return 1 IN main().
exit(EXIT_SUCCESS) is similar to return 0 IN main().
*/
exit(EXIT_FAILURE);
}
printf("Before free %p\n", ptr);
free(ptr); // no action occurs when ptr is NULL
printf("After free %p\n", ptr);
ptr = NULL; // optional
malloc으로 메모리를 할당했으면 꼭 free로 풀어줘야 한다.
ptr이란 변수는 { }을 벗어나면 사라지는데 메모리 할당이 사라진 것은 아니다.
/* Dynamically Allocated Array */
int n = 5;
ptr = (double*)malloc(n * sizeof(double));
if(ptr != NULL) // if(!ptr)
{
for (int i = 0; i < n; i++)
printf("%f", ptr[i]);
printf("\n");
for (int i = 0; i < n; i++)
*(ptr + i) = (double)i;
for (int i = 0; i < n; i++)
printf("%f", ptr[i]);
printf("\n");
}
free(ptr);
ptr = NULL;
동적할당을 이용한 배열만들기!
🪐동적 할당 메모리를 배열처럼 사용하기
1차원 배열
int n = 3;
int* ptr = (int*)malloc(sizeof(int*) * n);
if (!ptr) exit(1);
ptr[0] = 123;
*(ptr + 1) = 456;
*(ptr + 2) = 789;
free(ptr);
ptr = NULL;
2차원 배열을 1차원배열로 사용하기
int row = 3, col = 2;
int* ptr = (int*)malloc(row * col * sizeof(int));
if (!ptr) exit(1);
for (int r = 0; r < row; r++)
for (int c = 0; c < col; c++)
ptr[c + col * r] = c + col * r;
for (int r = 0; r < row; r++)
{
for (int c = 0; c < col; c++)
printf("%d ", *(ptr + c + col * r));
printf("\n");
}
🪐calloc(), realloc()
- calloc() ```c int n = 10;
int* ptr = NULL;
ptr = (int*)calloc(n, sizeof(int)); // Contiguous allocation if (!ptr) exit(1);
for (int i = 0; i < n; i++) printf(“%d “, ptr[i]); printf(“\n”);
calloc은 malloc과 다르게 개수와 크기를 입력받고 free를 안해줘도 된다.
* realloc()
```c
/*
realloc() KNK p. 422
- doesn't initialize the bytes added
- returns NULL if can't enlarge the memory block
- If first argument is NULL, it behaves like malloc()
- if second argument is 0, it frees the memory block.
*/
for (int i = 0; i < n; i++)
ptr[i] = i + 1;
n = 20;
int* ptr2 = NULL;
ptr2 = (int*)realloc(ptr, n * sizeof(int));
//ptr = (int*)realloc(ptr, n * sizeof(int)); 마치 기본 메모리 할당이 늘어난 것처럼 사용가능.
printf("%p %p\n", ptr, ptr2);
printf("%d\n", ptr[0]);
if (!ptr2) exit(1);
else ptr = NULL; // ptr로 realloc했다면 빼야됨.
for (int i = 0; i < n; i++)
printf("%d ", ptr2[i]); // copies data
printf("\n");
free(ptr2);
realloc은 재할당해주는 함수인데 메모리를 할당해준것에서 조정할 때 사용한다.
🪐포인터와 const 정리
float f1 = 3.14f, f2 = 1.2f;
const float* pf1 = &f1;
//*pf1 = 5.0f; //Error
pf1 = &f2; // Allowed
float* const pf2 = &f1;
*pf2 = 6.0f;
// pf2 = &f2; //Error
const float* const pf3 = &f1;
//*pf3 = 7.0f; //Error
//pf3 = &pf2; //Error