Void Type
- "Does not return a value", "No type"
- Used to store the address in void pointers
- Used when no return value is needed
Reference
type :🔗 https://en.cppreference.com/w/c/language/type
Main Function
The function called at program startup is named main.
Reference
main function : 🔗 https://en.cppreference.com/w/c/language/main_function
Dynamic Memory Allocation
Dynamic memory allocation is the process of allocating memory on the heap during program runtime, as needed.
Functions such as malloc(), calloc(), and realloc() are used to request memory, and the allocated memory must be released using the free() function once it's no longer needed.
These functions are defined in the <stdlib.h> header file.
Dynamic allocation is especially useful when the required memory size is not known at compile time or when handling large or flexible data structures.
malloc
void* malloc( size_t size );
Allocates a block of uninitialized memory of size bytes.
Click here to view the example code .▼
int *arr = (int*)malloc(5 * sizeof(int));
calloc
void* calloc( size_t num, size_t size );
Allocates memory for an array of num elements of size bytes each and initializes all bytes to zero.
- Unlike malloc, it performs zero-initialization.
Click here to view the example code .▼
int *arr = (int*)calloc(5, sizeof(int)); // Allocates and zero-initializes 5 integers
realloc
void *realloc( void *ptr, size_t new_size );
Resizes the memory block pointed to by ptr to new_size bytes.
- The content remains unchanged up to the minimum of the old and new sizes.
- The pointer may change, so always reassign the result.
Click here to view the example code .▼
arr = (int*)realloc(arr, 10 * sizeof(int)); // Resizes to hold 10 integers
free
void free( void *ptr );
Deallocates the memory previously allocated by malloc, calloc, or realloc.
Click here to view the example code .▼
free(arr);
References
malloc : 🔗 https://en.cppreference.com/w/c/memory/malloc
calloc : 🔗 https://en.cppreference.com/w/c/memory/calloc
realloc : 🔗 https://en.cppreference.com/w/c/memory/realloc
free : 🔗 https://en.cppreference.com/w/c/memory/free
Memory Functions
memcmp
int memcmp( const void* lhs, const void* rhs, size_t count );
Compares n bytes(size_t count) of two memory blocks.
Returns:
- Negative value if lhs appears before rhs in lexicographical order.
- Zero if lhs and rhs compare equal, or if count is zero.
- Positive value if lhs appears after rhs in lexicographical order.
Click here to view the example code .▼
char a[] = "abc";
char b[] = "abc";
if (memcmp(a, b, 3) == 0) {
printf("Equal\n");
}
memcpy
int* memcpy(void *dest, const void *src, size_t n);
Copies n bytes from source to destination.
- Fast and efficient for non-overlapping memory regions.
- Undefined behavior if src and dest overlap.
Click here to view the example code .▼
char src[] = "Hello";
char dest[6];
memcpy(dest, src, 6); // Copies 6 bytes including null terminator
memmove
void* memmove( void* dest, const void* src, size_t count );
Copies n bytes from source to destination, safe even if memory regions overlap.
- Internally handles overlap by using temporary buffer.
Click here to view the example code .▼
char str[] = "abcdef";
memmove(str + 2, str, 4); // Handles overlapping safely
memset
void* memset( void *dest, int ch, size_t count );
Sets the first num bytes of the memory block pointed to by ptr to the specified value.
- Commonly used to initialize arrays or reset buffers.
Click here to view the example code .▼
int arr[5];
memset(arr, 0, sizeof(arr)); // Sets all bytes in arr to 0
Learn More
Deifference between memcpy and memmove ▽
memcpy
- Used to copy n bytes from source to destination.
- Faster, but unsafe if memory regions overlap.
- Results in undefined behavior when source and destination overlap.
Example of Overlapping Memory (Why memcpy is unsafe)
char str[] = "abcdef";
memcpy(str + 2, str, 4); // Undifined behavior'
- str is the source → "abcd" (4 bytes)
- str + 2 is the destination → starts at 'c'
This causes overlapping between source and destination memory regions.
Since memcpy does not handle overlapping safely, the copy may overwrite part of the source before it finishes reading it.
This results in undefined behavior and corrupted data.
memmove
- Also copies n bytes from source to destination.
- Safe even when memory regions overlap.
- Slightly slower than memcpy due to internal checks or temporary buffer.
char str[] = "abcdef";
memmove(str + 2, str, 4); // Safe!
Internally, memmove ensures safe copying by adjusting the copy direction or utilizing a temporary buffer when necessary.

memset ▽
1. value is treated as a byte-wise value
The value passed to memset is not written as an integer, but as a single unsigned char (0~255) that fills each byte.
int arr[5];
memset(arr, -1, sizeof(arr)); // Fills memory with 0xFF
This sets every byte to 0xFF, which may result in -1 when viewed as an integer (on two's complement systems).
2. Be cautious when using memset with structs or non-byte data types
While zero-initializing a struct is safe, setting it to other values using memset can be unsafe or meaningless — especially for floating-point types or pointers.
struct A { int x; float y; };
memset(&obj, 0, sizeof(obj)); // ✅ Safe: Zero-initialization
memset(&obj, 1, sizeof(obj)); // ⚠️ Risky: Fills all bytes with 0x01, not meaningful for float
References
memcmp : 🔗 https://en.cppreference.com/w/c/string/byte/memcmp
memcpy : 🔗 https://en.cppreference.com/w/c/string/byte/memcpy
memmove:🔗 https://en.cppreference.com/w/c/string/byte/memmove
memset : 🔗 https://en.cppreference.com/w/c/string/byte/memset
Linked List
A linked list is a linear data structure where elements (nodes) are stored in separate memory locations.
Each node points to the next, allowing dynamic memory usage and flexible insertion/deletion.
Though not stored contiguously like arrays, it can be used similarly to access data sequentially.
Circular Linked List
A circular linked list is a variation where the last node points back to the first node.
This forms a loop, allowing continuous traversal without a NULL endpoint.
It's useful for scenarios like round-robin scheduling or circular buffers.
Circular Doubly Linked List Implementation in C
Click here to view the code I wrote.▼

#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node * nextNode;
struct Node * prevNode;
}Node;
Node *head = NULL;
int CountNode(Node* head){
if(head == NULL) {
return 0;
}
int cnt = 1;
Node* temp = head -> nextNode;
while (temp != head) {
++cnt;
temp = temp->nextNode;
}
return cnt;
}
int SearchNode(Node* head, Node* search) {
Node* temp = head;
while(temp != NULL){
if(temp == search) {
return temp -> data;
}
temp = temp -> nextNode;
if(temp == head){
break;
}
}
return -1;
}
Node* CreateNode(int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->nextNode = NULL;
newNode->prevNode = NULL;
return newNode;
}
void InsertNode(int data) {
Node* newNode = CreateNode(data);
if(head == NULL) {
head = newNode;
head -> nextNode = head;
head -> prevNode = head;
return;
}
Node* tail = head->prevNode;
tail -> nextNode = newNode;
newNode -> prevNode = tail;
newNode -> nextNode = head;
head -> prevNode = newNode;
}
void DeleteNode(int data){
Node* temp = head;
if(head->nextNode == head && head->data==data) {
free(head);
head = NULL;
return;
}
while(temp!= NULL){
if(temp->data == data) {
Node* prev = temp->prevNode;
Node* next = temp->nextNode;
prev->nextNode = next;
next->prevNode = prev;
if(temp == head){
head = next;
}
free(temp);
return;
}
temp = temp->nextNode;
if(temp == head){
break;
}
}
}
void PrintList() {
Node* temp = head;
printf("List : ");
while(temp != NULL){
printf("%d ", temp -> data);
temp = temp -> nextNode;
if(temp == head){
break;
}
}
if(temp == NULL) {
printf("Empty");
}
printf("\n");
}
void FreeList() {
Node* temp = head;
Node* nextNode;
while(temp != NULL){
nextNode = temp->nextNode;
free(temp);
temp = nextNode;
if(temp == head){
break;
}
}
head = NULL;
}
int main(){
int num1, num2,i, delete_num;
printf("Enter number of Nodes : ");
scanf("%d", &num1);
int *arr;
arr = (int*)malloc(sizeof(int) * num1);
printf("Enter Node values : ");
for(i=0; i<num1; ++i){
scanf("%d", &arr[i]);
InsertNode(arr[i]);
}
PrintList();
printf("Total Nodes : %d\n", CountNode(head));
printf("Enter Node index to search : ");
scanf("%d", &num2);
Node* search = head;
for(i=1;i<num2;++i) {
search = search->nextNode;
}
printf("searched Node value : %d\n", SearchNode(head, search));
printf("Enter value to delete : ");
scanf("%d", &delete_num);
DeleteNode(delete_num);
PrintList();
FreeList();
free(arr);
return 0;
}
Macro Function
A macro is a preprocessor directive that performs simple text substitution before compilation.
Try not to use macro functions.
Inline Function
An inline function suggests the compiler to replace a function call with the function’s actual code to reduce call overhead.
Note: With modern compiler optimization options enabled, the performance difference between regular functions and inline functions is often negligible.
'( * )Engineering > 🌜C/C++' 카테고리의 다른 글
Seminar (5) C++ : Namespace, Reference, OOP (0) | 2025.04.01 |
---|---|
Seminar (4) C (0) | 2025.03.31 |
Seminar (2) C (0) | 2025.03.13 |
Seminar (1) C (0) | 2025.03.11 |
[ATmega 128] 3. 7 Segment 타이머 만들기. (1) | 2024.03.29 |