Call by value vs Call by reference
call by value
- a copy of the variable is passed.
- changes made in a copy of variable never modify the value of variable outside the function.
- does not allow you to make any changed in the actual variables.
- actual and formal arguments will be created in different memory location.
- It is default in many programming languages.
call by reference
- a variable itself is passed.
- changes made in a variable also affects the value of the variable outside the function.
- allows you to make changes in the values of variables by using function calls.
- actual and formal arguments will be created in the same memory location.
- It is supported by most programming languages like Java, but not as default.
Dynamic Memory Allocation
What is malloc?
- a built-in function declared in the header file <stdlib.h>
- malloc is a short name of 'memory allocation'.
- if you specify some size in the malloc, and it will allocate a single large block of contiguous memory.
(void* )malloc(size_t size)
- the size have to be specified when you use malloc!!
- malloc will allocate a memory block according to the size specified in the heap.
- and when allocating is successed, it will return a 'void pointer'.
- it is pointing to the first byte of the allocated memory.
- when allocating is failed, malloc() will return 'NULL'.
- so the job of malloc is to allocate memory at run time.
- size_t is defined in <stdlib.h> as unsigned int. (the largest unsigned integer is possible.)
- so you can define size_t in a range of unsigned integer. it cannot be a negative number.

- here is a contiguous memory block that has been allocated by malloc().
- malloc will return a void pointer and we are assuming that this pointer is ptr.
- so the ptr is the pointer, which is pointing to this particular memory.
Whey malloc returns a 'void pointer'?
- because malloc doesn't have an idea of what it is pointing to.
- it means... malloc merely allocates memory for us
- without knowing what type of data will be stored in that memory location.
- that is why returning the void pointer.
- void pointer is a pointer which can point to any type of data.
- then, how it will know the size and type beforehand?
- It is our responsibility to typecast it.
- the void pointer can be typecasted to an appropriate type.
- so that we will use it in our program properly.
int *ptr = (int* )malloc(4)
- if you specifying 4, malloc will simply allocate 4 bytes of memory in the heap and return a void pointer.
(if the allocation is successed.) - in that case, we need to typecase it to an integer type of pointer.
- because we want to store an integer within that memory location.
- and after that, we will store the (returned and typecasted) pointer within some pointer of our choice. (ptr)
- the address of the first byte will be stored in the pointer 'ptr'.
example
#include <stdio.h>
#include <stdlib.h>
int main(){
int i, n;
printf("Enter the number of integers: ");
scanf("%d", &n);
int *ptr = (int* )malloc(n*sizeof(int));
if(ptr==NULL) {
printf("Memory not available.");
exit(1);
}
for(i=0; i<n; i++){
printf("Enter an integer: ");
scanf("%d ", *(ptr+i));
}
for(i=0; i<n; i++)
printf("%d ", *(ptr+i));
return 0;
}
- int *ptr = (int* )malloc(n*sizeof(int));
- we use sizeof() operator because we don't know what is the size of integer in our computer.
- the size of integer is multiplied with 'n'.
- we are asking the malloc to allocate the memory for n number of integers.
- malloc will return a void pointer and we are typecasting it to an integer pointer.
- and we are storing the address within this ptr pointer.
- if(ptr==NULL)
- if pointer contains NULL, it means that memory is not available.
- so we simply exit out of the program with the exit failure status.
- if this is not the case, then we can easily run the for loop from zero to n minus one.
- and we will ask the user to enter an integer one by one.
- scanf("%d ", *(ptr+i));
- why 'ptr', not '&ptr'?
- 'scanf("%d", &n) -> in this case, we need Ampersand because 'n' is representing the value.
- scanf requires the address. that is why we have to put Ampersand.
- but ptr is already giving us the address when we simply write ptr, which is a pointer.
- pointer contains the address, not a value. that is why there is no requirement of putting an Ampersand in front of it.
- printf("%d ", *(ptr+i));
- ptr contains the address of the first byte of the memory.
- if i is 0, *(ptr+i) will point the first location of the allocated memory.
so when we dereference it, we'll get the first integer. - if i is 1, *(ptr+i) will point the second address of the allocated memory.
if the first address is 1000, this will be interpreted 1004 if size of integer is 4.
so when we dereference it, we'll get the second integer.
calloc()
calloc()도 마찬가지로 stdlib.h를 통해 사용할 수 있는 함수이다.
둘 다 Heap 공간이 충분하지 않아서 메모리를 할당받지 못 할 때 NULL을 반환한다는 점은 동일한데 다른 점이 두 가지 있다.
1. malloc은 인자로 생성할 block size 하나만 주면 되지만, calloc은 인자로 block 하나의 사이즈와 block의 개수 두 개를 줘야 한다.
void *calloc(size_t n, size_t size);
- size_t n : number of blocks
- size_t size : size of each block
int *ptr = (int*)calloc(10, sizeof(int));
int *ptr = (int*)malloc(10*sizeof(int));
- 위 두 코드는 같은 역할을 한다.
2. malloc은 메모리가 할당되면 garbage value로 초기화되지만 calloc은 0으로 초기화된다.
- calloc은 메모리 공간의 초기값을 0으로 설정하고싶을 때 사용하면 좋다.
free()
malloc, calloc으로 할당한 메모리는 자동으로 해제되지 않는다.
따라서 동적으로 할당된 메모리를 OS에 돌려주기 위해 free()를 사용해야 한다.
메모리 누수가 발생되지 않게 하기 위해서는 동적 메모리를 꼭 free()로 해제해줘야 한다.
free(ptr)
ptr가 할당된 메모리의 포인터
메모리 블록을 해제하고 나서 포인터는 invalid해지고, 더 이상 유효한 메모리 공간을 가리키지 않는다.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr = (int *)calloc(sizeof(int), 5);
// Do some operations.....
for (int i = 0; i < 5; i++)
printf("%d ", ptr[i]);
// Free the memory after completing
// operations
free(ptr);
return 0;
}
free()를 호출한 후 포인터를 NULL로 만들어주는 게 좋다.
메모리의 할당 해제된 곳을 가리키는 'dangling pointer'를 피하기 위함이다.

Valgrind
메모리 누수를 탐지하는 리눅스용 디버깅 툴.
C에서는 malloc, calloc, relalloc 등으로 메모리를 동적 할당한 후 해제해주지 않으면 메모리 누수가 발생한다.
C는 메모리를 관리해주는 기능이 없어서 메모리 누수가 발생했는지 쉽게 탐지하기 힘든데 이 때 Valgrind라는 툴을 사용할 수 있다.
- 메모리 누수 탐지
- 유효하지 않은 메모리에 접근하지 못하게 막아줌
- 메모리 관련 에러 탐지 등
// C program causing a memory leak
#include <stdlib.h>
int main()
{
// Allocating memory without freeing it
int* ptr = (int*)malloc(sizeof(int));
return 0;
}
예를 들어 이렇게 메모리를 할당한 후 해제하지 않았을 때
valgrind --leak-check=full ./leak_example
이렇게 valgrind를 사용하여 메모리 누수를 탐지할 수 있다.
==12345== Memcheck, a memory error detector
==12345== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12345== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==12345== Command: ./memleak
==12345==
==12345==
==12345== HEAP SUMMARY:
==12345== in use at exit: 100 bytes in 1 blocks
==12345== total heap usage: 1 allocs, 0 frees, 100 bytes allocated
==12345==
==12345== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12345== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12345== by 0x108671: main (memleak.c:6)
==12345==
==12345== LEAK SUMMARY:
==12345== definitely lost: 100 bytes in 1 blocks
==12345== indirectly lost: 0 bytes in 0 blocks
==12345== possibly lost: 0 bytes in 0 blocks
==12345== still reachable: 0 bytes in 0 blocks
==12345== suppressed: 0 bytes in 0 blocks
==12345==
==12345== For counts of detected and suppressed errors, rerun with: -v
==12345== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
실행 결과 이런 output이 나오는데 소스코드의 어떤 부분에서 메모리가 할당되었고 누수가 발생했는지 등을 알려준다.
ref:
https://youtu.be/lCXohSvxbgo?si=Pz2p2L0cpUWs5KjX
https://youtu.be/Vch7_YeGKH4?si=gBsRc5cde3eEpXBA
https://www.youtube.com/watch?v=8q0jLDun0_0
https://www.geeksforgeeks.org/dynamic-memory-allocation-in-c-using-malloc-calloc-free-and-realloc/
Dynamic Memory Allocation in C using malloc(), calloc(), free() and realloc() - GeeksforGeeks
Your All-in-One Learning Portal: GeeksforGeeks is a comprehensive educational platform that empowers learners across domains-spanning computer science and programming, school education, upskilling, commerce, software tools, competitive exams, and more.
www.geeksforgeeks.org
'정글 > 컴퓨터 시스템' 카테고리의 다른 글
| 가상화(Virtualization) (2) | 2025.04.14 |
|---|---|
| [컴퓨터 시스템] 3장 (1~3) (0) | 2025.04.05 |