axl_memchr

This commit is contained in:
NukeBird 2025-12-03 16:49:54 +03:00
parent 7b20fdb03e
commit 774d0096d8
3 changed files with 120 additions and 35 deletions

View file

@ -238,6 +238,22 @@ i32 axl_memcmp(const void* s1, const void* s2, u32 n)
return 0;
}
void* axl_memchr(const void* ptr, u8 value, u32 n)
{
if(ptr)
{
for(u32 i = 0; i < n; i++)
{
if(*((u8*)ptr + i) == value)
{
return (u8*)ptr + i;
}
}
}
return NULL;
}
void axl_free(void* ptr)
{
if(!ptr)

View file

@ -13,6 +13,7 @@ void* axl_realloc(void* ptr, u32 size);
void* axl_memset(void* ptr, i8 c, u32 n);
void* axl_memcpy(void* dst, const void* src, u32 count);
i32 axl_memcmp(const void* s1, const void* s2, u32 n);
void* axl_memchr(const void* ptr, u8 value, u32 n);
void axl_free(void* ptr);
#endif

View file

@ -6,10 +6,6 @@
#include "axl_koan.h"
#include <string.h>
/* ------------------------------------------------------------------ */
/* Basic allocation & initialization */
/* ------------------------------------------------------------------ */
KOAN(init_called)
{
void* p = axl_malloc(1);
@ -30,14 +26,10 @@ KOAN(malloc_returns_different_pointers)
KOAN(malloc_exhaustion_returns_null)
{
void* p = axl_malloc(AXL_HEAP_SIZE + 4096); /* definitely too big */
void* p = axl_malloc(AXL_HEAP_SIZE + 4096);
ASSERT_NULL(p);
}
/* ------------------------------------------------------------------ */
/* Realloc behavior (strictly per C standard) */
/* ------------------------------------------------------------------ */
KOAN(realloc_null_acts_like_malloc)
{
void* p = axl_realloc(NULL, 64);
@ -52,7 +44,7 @@ KOAN(realloc_zero_size_frees_and_returns_null_or_valid)
ASSERT_NOT_NULL(p);
void* q = axl_realloc(p, 0);
if (q != NULL) axl_free(q);
/* Original p is freed regardless */
}
KOAN(realloc_enlarge_preserves_content)
@ -83,14 +75,10 @@ KOAN(realloc_same_size_returns_same_or_equivalent)
p = axl_realloc(p, 100);
ASSERT_NOT_NULL(p);
/* May return same or different pointer */
axl_free(p);
}
/* ------------------------------------------------------------------ */
/* Memory operations */
/* ------------------------------------------------------------------ */
KOAN(memset_fills_correctly)
{
void* p = axl_malloc(64);
@ -104,7 +92,7 @@ KOAN(memset_zero_bytes_is_nop)
{
void* p = axl_malloc(16);
axl_memset(p, 0xFF, 16);
axl_memset(p, 0x00, 0); /* should not change anything */
axl_memset(p, 0x00, 0);
for (int i = 0; i < 16; i++)
ASSERT_INT_EQ(0xFF, ((u8*)p)[i]);
axl_free(p);
@ -125,7 +113,7 @@ KOAN(memcpy_zero_bytes_is_nop)
u8 data[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
void* p = axl_malloc(16);
axl_memcpy(p, data, 16);
axl_memcpy(p, "junk", 0); /* must not modify */
axl_memcpy(p, "junk", 0);
ASSERT_INT_EQ(0, memcmp(p, data, 16));
axl_free(p);
}
@ -152,27 +140,115 @@ KOAN(memcmp_zero_length_returns_zero)
ASSERT_INT_EQ(0, axl_memcmp(&x, &y, 0));
}
/* ------------------------------------------------------------------ */
/* Double-free and use-after-free detection (indirect) */
/* ------------------------------------------------------------------ */
KOAN(memchr_finds_character_in_buffer)
{
u8 buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
void* result = axl_memchr(buffer, 0x03, sizeof(buffer));
ASSERT_NOT_NULL(result);
ASSERT_TRUE(result == &buffer[3]);
}
KOAN(memchr_returns_null_when_not_found)
{
u8 buffer[] = {0x10, 0x20, 0x30, 0x40, 0x50};
void* result = axl_memchr(buffer, 0x99, sizeof(buffer));
ASSERT_NULL(result);
}
KOAN(memchr_finds_first_occurrence)
{
u8 buffer[] = {0xAA, 0xBB, 0xCC, 0xBB, 0xDD};
void* result = axl_memchr(buffer, 0xBB, sizeof(buffer));
ASSERT_NOT_NULL(result);
ASSERT_TRUE(result == &buffer[1]);
}
KOAN(memchr_finds_at_beginning)
{
u8 buffer[] = {0xFF, 0xFE, 0xFD, 0xFC};
void* result = axl_memchr(buffer, 0xFF, sizeof(buffer));
ASSERT_NOT_NULL(result);
ASSERT_TRUE(result == &buffer[0]);
}
KOAN(memchr_finds_at_end)
{
u8 buffer[] = {0x11, 0x22, 0x33, 0x44, 0x55};
void* result = axl_memchr(buffer, 0x55, sizeof(buffer));
ASSERT_NOT_NULL(result);
ASSERT_TRUE(result == &buffer[4]);
}
KOAN(memchr_zero_length_returns_null)
{
u8 buffer[] = {0x01, 0x02, 0x03};
void* result = axl_memchr(buffer, 0x01, 0);
ASSERT_NULL(result);
}
KOAN(memchr_stops_at_specified_length)
{
u8 buffer[] = {0x10, 0x20, 0x30, 0x40, 0x50};
void* result = axl_memchr(buffer, 0x40, 3);
ASSERT_NULL(result);
result = axl_memchr(buffer, 0x40, 4);
ASSERT_NOT_NULL(result);
ASSERT_TRUE(result == &buffer[3]);
}
KOAN(memchr_handles_all_byte_values)
{
u8 buffer[256];
for (int i = 0; i < 256; i++) {
buffer[i] = (u8)i;
}
for (int i = 0; i < 256; i++) {
void* result = axl_memchr(buffer, (u8)i, sizeof(buffer));
ASSERT_NOT_NULL(result);
ASSERT_TRUE(result == &buffer[i]);
}
}
KOAN(memchr_matches_standard_memchr)
{
u8 buffer[100];
for (int i = 0; i < 100; i++) {
buffer[i] = (u8)(i * 3);
}
for (int val = 0; val < 256; val += 17) {
void* axl_result = axl_memchr(buffer, (u8)val, sizeof(buffer));
void* std_result = memchr(buffer, (u8)val, sizeof(buffer));
if (std_result == NULL) {
ASSERT_NULL(axl_result);
} else {
ASSERT_NOT_NULL(axl_result);
ASSERT_TRUE(axl_result == std_result);
}
}
}
KOAN(double_free_does_not_crash)
{
void* p = axl_malloc(64);
ASSERT_NOT_NULL(p);
axl_free(p);
axl_free(p); /* should be ignored or handled safely */
axl_free(p);
}
/* ------------------------------------------------------------------ */
/* Large and boundary allocations */
/* ------------------------------------------------------------------ */
KOAN(large_allocation_near_heap_limit)
{
/* Allocate almost entire heap */
void* p = axl_malloc(AXL_HEAP_SIZE - 1024);
ASSERT_NOT_NULL(p); /* may pass if overhead is small */
ASSERT_NOT_NULL(p);
if (p) axl_free(p);
}
@ -182,10 +258,6 @@ KOAN(allocation_of_max_size_fails)
ASSERT_NULL(p);
}
/* ------------------------------------------------------------------ */
/* Stress: many small allocations */
/* ------------------------------------------------------------------ */
KOAN(many_small_allocations)
{
#define N 1000
@ -201,10 +273,6 @@ KOAN(many_small_allocations)
}
}
/* ------------------------------------------------------------------ */
/* Main */
/* ------------------------------------------------------------------ */
int main(void)
{
axl_init();