#include #include #include #include #include "../source/stdlib/_mem.h" #define RUN_TEST(func) \ do { \ printf("---\tRUN TEST: %s\t---\n", #func); \ if (func()) { \ printf("[SUCCESS]\tTest %s is ok.\n\n", #func); \ } else { \ printf("[FAIL]\tTest %s failed.\n\n", #func); \ exit(EXIT_FAILURE); \ } \ } while (0) // c behind a and b #define IN_RANGE(a, b, c) (a > c && c > b) bool test_malloc_basic_allocation() { return malloc(sizeof(int)); } bool test_malloc_zero_bytes() { return malloc(0) == NULL; } bool test_malloc_multiple_allocations() { void* ptr[1024]; for (int i = 1; i < sizeof(ptr) / sizeof(*ptr); i++) { ptr[i] = malloc(i); if (ptr[i] == NULL) { printf("fail alloc %d bytes\n", i); return false; } } for (int i = 1; i < sizeof(ptr) / sizeof(*ptr); i++) { for (int j = i + 1; j < sizeof(ptr) / sizeof(*ptr) - i - 1; j++) { if (ptr[i] == ptr[j]) { printf("ptrs[%d] == ptrs[%d].\n", i, j); return false; } else if (IN_RANGE( GET_MEM_NODE_HEADER(ptr[i])->size + (char*)GET_MEM_NODE_HEADER(ptr[i]), (char*)ptr[i], (char*)GET_MEM_NODE_HEADER(ptr[j]))) { printf("node %p in node %p", GET_MEM_NODE_HEADER(ptr[i]), GET_MEM_NODE_HEADER(ptr[j])); // additional info printf("node %p\nsize:%p\nfree:%p\nnext: %p\nlast: %p\n", GET_MEM_NODE_HEADER(ptr[i]), GET_MEM_NODE_HEADER(ptr[i])->size, GET_MEM_NODE_HEADER(ptr[i])->free, GET_MEM_NODE_HEADER(ptr[i])->next, GET_MEM_NODE_HEADER(ptr[i])->last); printf("node %p\nsize:%p\nfree:%p\nnext: %p\nlast: %p\n", GET_MEM_NODE_HEADER(ptr[j]), GET_MEM_NODE_HEADER(ptr[j])->size, GET_MEM_NODE_HEADER(ptr[j])->free, GET_MEM_NODE_HEADER(ptr[j])->next, GET_MEM_NODE_HEADER(ptr[j])->last); exit(EXIT_FAILURE); } } } return true; } bool test_malloc_data_integrity() { char* A = (char*)malloc(10); char* B = (char*)malloc(10); char* C = (char*)malloc(10); if (!A || !B || !C) { printf("can't alloc\n"); free(A); free(B); free(C); return false; } strcpy(A, "AAA"); strcpy(C, "CCC"); free(B); if (strcmp(A, "AAA") != 0) { printf("A data is broken after free(B). A = '%s'\n", A); free(A); free(C); return false; } if (strcmp(C, "CCC") != 0) { printf("C data is broken after free(B). C = '%s'\n", C); free(A); free(C); return false; } free(A); free(C); return true; } bool test_malloc_large_allocation() { return malloc(1024 * 1024 * 8); // alloc 4mb } bool test_malloc_allocation_and_free() { free(malloc(sizeof(int))); return true; } int main() { RUN_TEST(test_malloc_basic_allocation); RUN_TEST(test_malloc_zero_bytes); RUN_TEST(test_malloc_multiple_allocations); RUN_TEST(test_malloc_data_integrity); RUN_TEST(test_malloc_large_allocation); RUN_TEST(test_malloc_basic_allocation); return 0; }