This project demonstrates two implementations of a stack in Rust: a safe implementation using Vec
and an unsafe implementation using raw pointers for manual memory management. The project includes:
- Benchmarks: Comparing performance between safe and unsafe implementations using
criterion
. - Fuzzing: Testing the robustness of the stack implementations using
cargo-fuzz
.
- Safe Implementation:
- Uses
Vec
for memory safety. - Minimal risk of undefined behavior.
- Uses
- Unsafe Implementation:
- Manages memory manually using raw pointers.
- Optimized for performance-critical use cases.
- Tests allocation, deallocation, and pointer arithmetic.
cargo
for building and managing dependencies
For benchmarks and fuzzing:
- Install
criterion
for benchmarks. - Install
cargo-fuzz
for fuzz testing (requires nightly toolchain).
git clone https://github.com/sunsided/fixedstack-rs.git
cd fixedstack-rs
just build
# or
cargo build
just test
# or
cargo test
Benchmarks are implemented using the Criterion crate. To run benchmarks:
just bench
# or
cargo bench
This compares the performance of push
and pop
operations for both safe and unsafe stack implementations.
Fuzz tests are implemented using cargo-fuzz. Fuzzing helps uncover edge cases and undefined behavior, especially in the unsafe implementation.
cargo install cargo-fuzz
just fuzz
# or
cargo fuzz run fuzz_stack
When the fuzzer finds a failing input, the test case is saved in fuzz/artifacts/fuzz_stack/
. To reproduce the failure:
cargo fuzz run fuzz_stack fuzz/artifacts/fuzz_stack/<failing-input>
You can also minimize failing inputs for easier debugging:
cargo fuzz tmin fuzz_stack fuzz/artifacts/fuzz_stack/<failing-input>
.
├── src
│ ├── lib.rs # Main library code for stack implementations
│ ├── stack_safe.rs # Safe stack implementation
│ └── stack_unsafe.rs # Unsafe stack implementation
│
├── benches
│ └── benchmarks.rs # Criterion benchmarks
│
└── fuzz
├── fuzz_targets # Directory for fuzzing targets
└── fuzz_stack.rs # Fuzz target for stack testing
use stack_experiments::stack_unsafe::FixedStack;
fn main() {
let mut stack = FixedStack::new(3);
stack.push(1);
stack.push(2);
println!("{:?}", stack.pop()); // Output: Some(2)
println!("{:?}", stack.pop()); // Output: Some(1)
}
use stack_experiments::stack_unsafe::FixedStack;
fn main() {
let mut stack = FixedStack::new(3);
stack.push(1);
stack.push(2);
println!("{:?}", stack.pop()); // Output: Some(2)
println!("{:?}", stack.pop()); // Output: Some(1)
}
Contributions are welcome! Feel free to fork the repository, create a feature branch, and submit a pull request.
This project is licensed under the EUPL-1.2 License. See LICENSE for details.