#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
// 1. Object, Identifier.
int var_name = 314;
//변수의 memory 공간 = object, 변수 이름 var_name = identifier.
int* pt = &var_name;
//포인터의 memory 공간 = object, 변수 이름 pt = identifier.
*pt = 1;
//*pt는 object를 나타내며, identifier가 아님.
int arr[100];
//배열 이름 arr = identifier.
//arr = arr자체의 memory 주소가 아닌, arr[0]의 memory 주소를 가리키므로 object가 아님.
arr[0];
//arr[0] = object이며, identifier가 아니고 expression임.
// 2. L-value, R-value.
var_name = 314;
//var_name = lvalue.
int temp = var_name;
//var_name = rvalue.
pt = &var_name;
//pt = lvalue, &var_name = rvalue.
int* ptr = arr;
//ptr = lvalue, arr = rvalue.
*pt = 7;
//*pt = lvalue, 7 = rvalue.
int* ptr2 = arr + 2 * var_name;
//ptr2 = lvalue, arr + 2 * var_name = rvalue.
*(arr + 2 * var_name) = 456;
//*(arr + 2 * var_name) = lvalue, 456 = rvalue.
const char* str = "Constant string";
//str = lvalue, "Constant string" = rvalue.
str = "Second string";
//str = lvalue, "Second string" = rvalue.
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int g_i = 123; //전역 변수(global variable), file scope.
int g_j; //전역 변수(global variable), file scope.
void f1(int hello, double world); // function prototype scope.
void func1()
{
g_i++; //전역 변수 g_i 사용.
}
void func2()
{
g_i += 2; //전역 변수 g_i 사용.
}
int main()
{
int local = 314; // function scope. (main())
{
local = 999; // block scope.
}
func1();
func2();
printf("%d\n", g_i); //전역 변수 g_i 사용.
printf("%d\n", g_j);
//초기화 되지 않은 전역 변수 g_j = BSS Segment memory에 저장되며, BSS Segment에 저장된 변수는 전부 0 으로 초기화 됨.
printf("%d\n", local);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int el; //external linkage.
static int il; //internal linkage.
void testLinkage(); //testLinkage() 함수 프로토타입.
int main()
{
el = 1024; // 전역 변수 el에 1024 저장.
testLinkage(); //testLinkage() 함수 실행.
printf("%d\n", el); // el 값 출력.
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
extern int el; // 다른 소스 파일에서 선언된 변수 el을 가져옴.
void testLinkage() // testLinkage() 함수 정의.
{
printf("DoSomething called\n");
printf("%d\n", el); // el 값 출력.
el++; // el 값에 1 더함.
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void func(int k); //함수 프로토타입에서 지역 변수 k 선언.
int main()
{
auto int a; //auto : 지역 변수 임을 강조하는 키워드.
a = 1024;
int i = 1; //지역 변수 i 초기화.
int j = 2; //지역 변수 j 초기화.
printf("i %lld\n", (long long)&i); //main() 지역변수 i의 메모리 주소 출력.
{
int i = 3; //내부 영역(scope)에서 지역 변수 i 초기화.
printf("i %lld\n", (long long)&i); //내부 영역 지역변수 i의 메모리 주소 출력.
printf("j = %d\n", j); //j의 값 출력. (내부 영역에서 상위 영역의 변수 사용 가능)
}
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void temp(register int r); //함수 프로토타입에서 레지스터 변수 r 선언.
int main()
{
register int r; //레지스터 변수 r 선언.
r = 123;
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
static int el; //internal linkage가 가능한 전역 변수 el 선언.
void testLinkage(); //testLinkage() 함수 프로토타입.
int main()
{
el = 1024; // internal linkage 전역 변수 el에 1024 저장.
// extern int g_int; -> extern 사용은 옵션임.
testLinkage(); //testLinkage() 함수 실행.
printf("%d\n", el); // el 값 출력.
return 0;
}
void testLinkage() // testLinkage() 함수 정의.
{
printf("DoSomething called\n");
printf("%d\n", el); // el 값 출력.
el++; // el 값에 1 더함.
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int el; //external linkage가 가능한 전역 변수 el 선언.
void testLinkage(); //testLinkage() 함수 프로토타입.
int main()
{
el = 1024; // 전역 변수 el에 1024 저장.
testLinkage(); //testLinkage() 함수 실행.
printf("%d\n", el); // el 값 출력.
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
extern int el; // 다른 소스 파일에서 선언된 external linkage가 가능한 전역 변수 el을 가져옴. (extern)
void testLinkage() // testLinkage() 함수 정의.
{
printf("DoSomething called\n");
printf("%d\n", el); // el 값 출력.
el++; // el 값에 1 더함.
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void count()
{
int ct = 0; // count() 함수의 지역 변수 ct 선언.
printf("count = %d %lld\n", ct, (long long)&ct); //ct 값과 ct memory 주소 출력.
ct++; // ct에 1 더함.
}
void static_count()
{
static int ct = 0; //static_count() 함수의 static 지역 변수 ct 선언.
printf("count = %d %lld\n", ct, (long long)&ct); //ct 값과 ct memory 주소 출력.
ct++; // ct에 1 더함.
}
int main()
{
count(); // count() 함수 호출.
count(); // count() 함수 호출. 함수를 호출할 때마다 변수가 계속 초기화 됨.
static_count(); // static_count() 호출.
static_count(); // static_count() 호출. 함수를 호출할 때마다 기존 변수가 계속 사용됨.
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> // malloc(), free() 사용.
int main()
{
int n = 5; // 변수 n 초기화.
double* ptr = NULL; // 포인터 변수 ptr 초기화.
ptr = (double*)malloc(n * sizeof(double)); // 포인터 변수 ptr에 동적 할당된 memory 주소 저장.
if (ptr == NULL) // ptr이 NULL일 경우 = memory 동적 할당이 안된 경우
{
puts("Memory allocation failed."); // Memory 할당 실패 출력.
exit(EXIT_FAILURE); // 프로그램 강제 종료. (return 1)
}
else { // memory 동적 할당이 된 경우.
for (int i = 0; i < n; ++i) // n 만큼 반복 실행.
{
*(ptr + i) = i; // ptr의 첫번 째 memory 주소 값부터 차례대로 i 대입.
printf("%f ", ptr[i]); // ptr의 첫번 째 memory 주소 값부터 차례대로 출력.
}
}
free(ptr); // 사용된 동적 할당 memory 반납.
ptr = NULL; // 사용된 동적 할당 memory 용 포인터 변수 값 NULL 초기화.
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> // malloc(), free() 사용.
int main()
{
for (int k = 0; k < 1000000; ++k)
{
int n = 100000000;
int* ptr = (int*)malloc(n * sizeof(int)); // 100000000 * 4 bytes = 약 300 MB.
if (!ptr) // = if (ptr == NULL)
{
printf("Malloc() failed\n"); // 동적 할당 실패 출력.
exit(EXIT_FAILURE); // 프로그램 강제 종료. (return 1)
}
for (int i = 0; i < n; ++i) // n 만큼 반복 실행.
{
ptr[i] = i + 1; // ptr 첫번 째 memory 주소부터 차례대로 i+1 저장.
}
free(ptr); // 사용한 동적 할당 memory 반납. (300 MB)
ptr = NULL; // 사용한 동적 할당 memory 용 포인터 변수 NULL 초기화.
}
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> // malloc(), free() 사용.
int main()
{
for (int k = 0; k < 1000000; ++k) // for 문 실행마다 memory 300 MB 씩 누수.
{
int n = 100000000;
int* ptr = (int*)malloc(n * sizeof(int)); // 100000000 * 4 bytes = 약 300 MB.
if (!ptr) // = if (ptr == NULL)
{
printf("Malloc() failed\n"); // 동적 할당 실패 출력.
exit(EXIT_FAILURE); // 프로그램 강제 종료. (return 1)
}
for (int i = 0; i < n; ++i) // n 만큼 반복 실행.
{
ptr[i] = i + 1; // ptr 첫번 째 memory 주소부터 차례대로 i+1 저장.
}
//free(ptr); // 사용한 동적 할당 memory 반납 안함 = memory 누수 발생.
//ptr = NULL;
}
return 0;
}
💡 디버깅 하다가 3번 정도 memory 누수 되니까 프로그램 갑자기 종료 됨.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> // malloc(), calloc(), realloc(), free() 사용.
int main()
{
int n = 10;
int* ptr = NULL;
ptr = (int*)calloc(n, sizeof(int)); // calloc() 함수로 4 bytes 크기의 memory 공간을 n개 만큼 할당 받음.
if (!ptr)
exit(1);
for (int i = 0; i < n; ++i)
{
printf("%d ", ptr[i]); // ptr[i] 값 출력.
printf("\n");
printf("%p ", &ptr[i]); // ptr[i] 값의 memory 주소 출력.
printf("\n");
}
printf("\n");
for (int i = 0; i < n; ++i)
{
ptr[i] = i + 1; // ptr[0] ~ ptr[9] 까지 1 ~ 9를 차례대로 대입.
}
n = 20; // n에 20 대입.
int* ptr2 = NULL; // ptr2 초기화.
ptr2 = (int*)realloc(ptr, n * sizeof(int));
// realloc() 함수를 사용하여 ptr의 memory 크기를 수정하여 만들어진 memory의 첫번째 주소를 ptr2에 저장하고 ptr의 memory 반납.
printf("%p %p\n", ptr, ptr2); // ptr, ptr2 의 memory 주소 출력.
printf("%d\n", ptr[0]); // ptr[0]의 값 출력.
if (!ptr2) // realloc() 함수로 동적 할당을 못 받은 경우.
exit(1); // 프로그램 강제 종료.
else
ptr = NULL; // realloc() 함수 정상 실행 후 기존의 ptr은 사용되지 않으므로 NULL 초기화.
for (int i = 0; i < n; ++i) // n 만큼 반복 실행.
printf("%d ", ptr2[i]); // ptr2[0] ~ ptr2[19] 의 값 차례대로 출력.
printf("\n");
free(ptr2); // 더 이상 사용하지 않는 ptr2 의 memory 반납.
return 0;
}
🚩 출처 및 참고자료 : 홍정모의 따라하며 배우는 C 언어 (따배씨)