- Published on
Dynamic Arrays
- Authors
- Name
- Vishok Manikantan
Array
To understand dynamic arrays, let's first understand the array data structure.
An array is a collection of elements stored in contiguous memory locations. Each element in the array is accessed using an index. The index starts from 0 and goes up to the size of the array minus one. They allow us to store multiple elements of the same type, making it easier to manage and access the data.
Dynamic Arrays
Dynamic arrays are arrays that can grow or shrink in size during runtime. They are also known as resizable arrays. Unlike static arrays, where the size must be defined at the time of compilation, dynamic arrays provide flexibility in managing memory.
Why Use Dynamic Arrays?
- Flexibility: You can add or remove elements as needed without worrying about the initial size.
- Memory Efficiency: They allocate memory as needed, which can help optimize resource usage.
- Ease of Use: Dynamic arrays simplify the process of handling collections of data without needing to manage memory manually.
A Shopping Cart
Imagine you have a shopping cart where you can put
items and remove
items. The cart can grow or shrink based on the items you add or remove. This is similar to how dynamic arrays work.
Let's implement a simple shopping cart using dynamic arrays.
Operations
Any shopping cart could do the following operations:
- Put: Add items to the cart.
- Remove: Remove items from the cart.
- Display: Display the items in the cart.
Implementation
Before implementing the shopping cart, let's understand the structure of the data we are trying to implement.
Structure Definition
If you are not familiar with structures in C, you can read about them here.
We first need to define our dynamic array structure:
struct DynamicArray {
int *array;
int size;
int capacity;
};
In this structure, we have three fields:
array
: A pointer to the array that stores the elements.size
: The current number of elements in the array.capacity
: The maximum number of elements the array can hold.
Initialization
To initialize our dynamic array, we need to allocate memory for the array and set the initial size and capacity:
struct DynamicArray cart;
cart.array = (int *)malloc(sizeof(int) * 2);
cart.size = 0;
cart.capacity = 2;
In this snippet, we allocate memory for the array to hold two elements initially. We set the size to 0 and the capacity to 2.
Put Operation
To add items to the cart, we need to implement the put
operation:
void put(struct DynamicArray *cart, int item) {
if (cart->size == cart->capacity) {
cart->capacity *= 2;
cart->array = (int *)realloc(cart->array, sizeof(int) * cart->capacity);
}
cart->array[cart->size++] = item;
}
In this function, we check if the current size of the array is equal to the capacity. If it is, we double the capacity and reallocate memory for the array. We then add the item to the array. This operation ensures that the array grows dynamically as needed.
Remove Operation
To remove items from the cart, we implement the remove
operation:
void remove(struct DynamicArray *cart) {
if (cart->size > 0) {
cart->size--;
}
}
In this function, we decrement the size of the array if it is greater than 0. This operation allows us to remove items from the array.
Display Operation
To display the items in the cart, we implement the display
operation:
void display(struct DynamicArray cart) {
printf("Items in the cart: ");
for (int i = 0; i < cart.size; i++) {
printf("%d ", cart.array[i]);
}
printf("\n");
}
In this function, we iterate over the elements in the array and print them to the console. This operation helps us visualize the items in the cart.
Putting It All Together
Now that we have implemented the basic operations, let's see how we can use them:
int main() {
struct DynamicArray cart;
cart.array = (int *)malloc(sizeof(int) * 2);
cart.size = 0;
cart.capacity = 2;
put(&cart, 10);
put(&cart, 20);
put(&cart, 30);
display(cart);
remove(&cart);
display(cart);
return 0;
}
In this snippet, we create a dynamic array cart
, add items to it, display the items, remove an item, and display the updated items.
A Practical Example: Fastre
Well, Fastre is a lightweight, fast runtime engine for efficient server-side rendering and dynamic content handling, using a HTML like syntax.
How Dynamic Arrays and Fastre are related?
When Fastre parses a request, it also parses the Cookie
header.
Cookies are basically key-value pairs stored in the client's (visitor's) browser. When a client sends a request to the server, the server can read the cookies to identify the client.
Fastre uses dynamic arrays to store these key-value pairs. The array grows as more cookies are added and shrinks as cookies are removed.
The following snippets are from the Fastre source code itself.
Implementation
A dynamic array is simpler to implement in javascript, as the language handles memory allocation and resizing automatically. By default, javascript arrays are dynamic.
The Cookie Structure in Fastre:
export let cookie = [];
Adding a Cookie
To add a cookie, we use the push
method:
export function appendCookie(str){
cookie.push(str);
}
Clearing Cookies
To clear all cookies, we simply reinitialize the array:
export function clearCookies(){
cookie = [];
}
Accessing Cookies
To access cookies, we can simply parse the request headers, and add it one by one:
export default function getCookies(req){
if (!req.headers.cookie){
return {};
}
const cookies = req.headers.cookie.split(';');
for (const cookie of cookies){
const [key, value] = cookie.split('=');
appendData(key, value);
}
return true;
}
Usage
Now, let's see how the cookie array is used in Fastre:
if (!getCookies(req)){
log("Error parsing cookies", "error");
}
In this snippet, we parse the cookies from the request headers and log an error if there is an issue.
Conclusion
Dynamic arrays provide flexibility and efficiency in managing collections of data. They allow us to resize arrays as needed, making them suitable for scenarios where the size of the data is not known in advance. By understanding and implementing dynamic arrays, we can build more robust and scalable applications that can adapt to changing requirements.
We also saw how Fastre uses dynamic arrays to manage cookies efficiently, demonstrating a practical use case for this data structure.
I hope this post helped you understand dynamic arrays better. If you have any questions or feedback, feel free to leave a comment below.
Happy coding! 🚀