diff --git a/unsafe_stack/.gitignore b/unsafe_stack/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..b83d22266ac8aa2f8df2edef68082c789727841d
--- /dev/null
+++ b/unsafe_stack/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/unsafe_stack/Cargo.toml b/unsafe_stack/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..9d6158852daf2e273cf62b04fd7602edce9000ac
--- /dev/null
+++ b/unsafe_stack/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "unsafe_stack"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/unsafe_stack/src/main.rs b/unsafe_stack/src/main.rs
new file mode 100644
index 0000000000000000000000000000000000000000..97a00b3f37966a3c255ea563cc0051fbd2300b26
--- /dev/null
+++ b/unsafe_stack/src/main.rs
@@ -0,0 +1,16 @@
+use unsafe_stack::{Stack, StackError};
+mod unsafe_stack;
+
+fn main() -> Result<(), StackError> {
+    let mut new_stack: Stack<f64> = Stack::new(10).unwrap();
+
+    for i in 0..new_stack.capacity {
+        unsafe {
+            new_stack.push(i as f64).unwrap();
+        }
+    }
+
+    println!("{}", new_stack);
+
+    Ok(())
+}
diff --git a/unsafe_stack/src/unsafe_stack/mod.rs b/unsafe_stack/src/unsafe_stack/mod.rs
new file mode 100644
index 0000000000000000000000000000000000000000..346df6c5471355396123fcb7f8424172d189b60a
--- /dev/null
+++ b/unsafe_stack/src/unsafe_stack/mod.rs
@@ -0,0 +1,78 @@
+#[derive(Debug)]
+pub enum StackError {
+    AllocationFailed,
+    StackFull,
+    StackEmpty,
+}
+
+#[derive(Debug)]
+pub struct Stack<T> {
+    pointer: *mut T,
+    length: usize,
+    pub capacity: usize,
+}
+
+impl<T: Copy + std::fmt::Display> std::fmt::Display for Stack<T> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        Ok(for i in 0..self.capacity {
+            unsafe {
+                write!(f, "{} ", *self.pointer.offset(i as isize) as T)?;
+            }
+        })
+    }
+}
+
+#[allow(dead_code)]
+impl<T: Copy> Stack<T> {
+    pub fn new(capacity: usize) -> Result<Self, StackError> {
+        unsafe {
+            let layout = std::alloc::Layout::array::<T>(capacity);
+
+            if let Ok(val) = layout {
+                let ptr = std::alloc::alloc(val);
+                if ptr.is_null() {
+                    return Err(StackError::AllocationFailed);
+                }
+
+                Ok(Self {
+                    pointer: ptr as *mut T,
+                    length: 0,
+                    capacity,
+                })
+            } else {
+                Err(StackError::AllocationFailed)
+            }
+        }
+    }
+
+    pub fn is_full(&self) -> bool {
+        self.length == self.capacity
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.length == 0
+    }
+
+    pub unsafe fn push(&mut self, value: T) -> Result<(), StackError> {
+        match self.is_full() {
+            true => Err(StackError::StackFull),
+            false => unsafe {
+                let location = self.pointer.offset(self.length as isize);
+                *location = value;
+                self.length += 1;
+                Ok(())
+            },
+        }
+    }
+
+    pub unsafe fn pop(&mut self) -> Result<T, StackError> {
+        match self.is_empty() {
+            true => Err(StackError::StackEmpty),
+            false => unsafe {
+                let location = self.pointer.offset(self.length as isize - 1);
+                self.length -= 1;
+                Ok(*location)
+            },
+        }
+    }
+}