125 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
 | 
						|
// Dynamic Storage Allocation: First Fit & Best Fit
 | 
						|
// Optimized for minimal code size (e.g., for writing on paper)
 | 
						|
 | 
						|
// Block structure: s=start, z=size, p=process_id (0 if free)
 | 
						|
struct B {int s, z, p;} *b;
 | 
						|
int nb = 0, cap = 4, mem_sz; // num_blocks, capacity, total_memory_size
 | 
						|
 | 
						|
// insb: insert block at index idx, maintain order by start address 's'
 | 
						|
void insb(int idx, int s, int z, int p) {
 | 
						|
    if (nb >= cap) {
 | 
						|
        cap *= 2;
 | 
						|
        b = realloc(b, cap * sizeof(struct B));
 | 
						|
        // Note: Real-world code checks realloc failure. Skipped for brevity.
 | 
						|
    }
 | 
						|
    for (int k = nb; k > idx; k--) b[k] = b[k-1]; // Shift right
 | 
						|
    b[idx] = (struct B){s, z, p};
 | 
						|
    nb++;
 | 
						|
}
 | 
						|
 | 
						|
// rmb: remove block at index idx
 | 
						|
void rmb(int idx) {
 | 
						|
    for (int k = idx; k < nb - 1; k++) b[k] = b[k+1]; // Shift left
 | 
						|
    nb--;
 | 
						|
}
 | 
						|
 | 
						|
// pb: print current blocks state
 | 
						|
void pb() {
 | 
						|
    printf("Mem:[");
 | 
						|
    // Print each block: start:size! (allocated) or start:size (free)
 | 
						|
    for(int i=0; i<nb; i++) printf(" %d:%d%s", b[i].s, b[i].z, b[i].p ? "!" : "");
 | 
						|
    printf(" ]\n");
 | 
						|
}
 | 
						|
 | 
						|
// ff: First Fit allocation
 | 
						|
void ff(int pid, int sz) {
 | 
						|
    int f = -1; // found index
 | 
						|
    for (int i = 0; i < nb; i++) { // Find first free block large enough
 | 
						|
        if (!b[i].p && b[i].z >= sz) { f = i; break; }
 | 
						|
    }
 | 
						|
    if (f != -1) { // Block found
 | 
						|
        if (b[f].z > sz) { // Need to split block
 | 
						|
            // Insert new free block for the remainder after the allocated part
 | 
						|
            insb(f + 1, b[f].s + sz, b[f].z - sz, 0);
 | 
						|
            b[f].z = sz; // Adjust size of the now-allocated block
 | 
						|
        }
 | 
						|
        b[f].p = pid; // Mark block as allocated to pid
 | 
						|
        printf("FF OK P%d->%d@%d\n", pid, sz, b[f].s);
 | 
						|
    } else printf("FF Fail P%d(%d)\n", pid, sz); // Allocation failed
 | 
						|
    pb(); // Show memory state
 | 
						|
}
 | 
						|
 | 
						|
// bf: Best Fit allocation
 | 
						|
void bf(int pid, int sz) {
 | 
						|
    int bi = -1, min_z = mem_sz + 1; // best_index, min_suitable_size
 | 
						|
    for (int i = 0; i < nb; i++) { // Find smallest free block large enough
 | 
						|
        if (!b[i].p && b[i].z >= sz && b[i].z < min_z) {
 | 
						|
            min_z = b[i].z; // Update best size found
 | 
						|
            bi = i;         // Update best index found
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (bi != -1) { // Best fit block found
 | 
						|
        if (b[bi].z > sz) { // Need to split block
 | 
						|
             // Insert new free block for the remainder
 | 
						|
            insb(bi + 1, b[bi].s + sz, b[bi].z - sz, 0);
 | 
						|
            b[bi].z = sz; // Adjust size of the allocated block
 | 
						|
        }
 | 
						|
        b[bi].p = pid; // Mark block allocated
 | 
						|
        printf("BF OK P%d->%d@%d\n", pid, sz, b[bi].s);
 | 
						|
    } else printf("BF Fail P%d(%d)\n", pid, sz); // Allocation failed
 | 
						|
    pb(); // Show memory state
 | 
						|
}
 | 
						|
 | 
						|
// de: Deallocate block associated with pid
 | 
						|
void de(int pid) {
 | 
						|
    int f = -1; // found index
 | 
						|
    for (int i = 0; i < nb; i++) if (b[i].p == pid) { f = i; break; } // Find block by pid
 | 
						|
 | 
						|
    if (f != -1) { // Block found
 | 
						|
        printf("De OK P%d@%d(%d)\n", pid, b[f].s, b[f].z);
 | 
						|
        b[f].p = 0; // Mark block as free
 | 
						|
 | 
						|
        // Try merging with the *next* block if it exists and is free
 | 
						|
        if (f + 1 < nb && !b[f+1].p) {
 | 
						|
            b[f].z += b[f+1].z; // Absorb next block's size
 | 
						|
            rmb(f + 1);         // Remove the next block entry
 | 
						|
        }
 | 
						|
        // Try merging with the *previous* block if it exists and is free
 | 
						|
        if (f > 0 && !b[f-1].p) {
 | 
						|
            b[f-1].z += b[f].z; // Add current block's size to previous
 | 
						|
            rmb(f);             // Remove the current block entry (now merged)
 | 
						|
            // f = f-1; // If index 'f' were needed after merge, adjust it
 | 
						|
        }
 | 
						|
         pb(); // Show memory state
 | 
						|
    } else printf("De Fail P%d\n", pid); // Deallocation failed (pid not found)
 | 
						|
}
 | 
						|
 | 
						|
// Main driver loop
 | 
						|
int main() {
 | 
						|
    printf("MemSz:"); scanf("%d", &mem_sz); // Get total memory size
 | 
						|
    b = malloc(cap * sizeof(struct B));     // Allocate initial block array
 | 
						|
    if (!b) return 1; // Handle malloc failure
 | 
						|
    b[0] = (struct B){0, mem_sz, 0};        // Create the first block (all memory, free)
 | 
						|
    nb = 1;
 | 
						|
    pb(); // Show initial state
 | 
						|
 | 
						|
    int choice, pid, sz;
 | 
						|
    printf("1:FF 2:BF 3:Dealloc 0:Exit\n");
 | 
						|
    // Loop until user enters 0
 | 
						|
    while(scanf("%d", &choice) == 1 && choice) {
 | 
						|
        if (choice == 1 || choice == 2) { // Allocate request
 | 
						|
            printf("PID Sz:"); scanf("%d%d", &pid, &sz);
 | 
						|
            if (choice == 1) ff(pid, sz); else bf(pid, sz);
 | 
						|
        } else if (choice == 3) { // Deallocate request
 | 
						|
            printf("PID:"); scanf("%d", &pid);
 | 
						|
            de(pid);
 | 
						|
        } else printf("?\n"); // Invalid choice
 | 
						|
        printf("1:FF 2:BF 3:Dealloc 0:Exit\n"); // Prompt again
 | 
						|
    }
 | 
						|
 | 
						|
    free(b); // Free the block array memory
 | 
						|
    return 0;
 | 
						|
}
 |