diff --git a/stan/math/memory/stack_alloc.hpp b/stan/math/memory/stack_alloc.hpp
index 4706473c384..8a8ef2cc7c1 100644
--- a/stan/math/memory/stack_alloc.hpp
+++ b/stan/math/memory/stack_alloc.hpp
@@ -158,7 +158,9 @@ class stack_alloc {
* Return a newly allocated block of memory of the appropriate
* size managed by the stack allocator.
*
- * The allocated pointer will be 8-byte aligned.
+ * The allocated pointer will be 8-byte aligned. If the number
+ * of bytes requested is not a multiple of 8, the reserved space
+ * will be padded up to the next multiple of 8.
*
* This function may call C++'s malloc()
function,
* with any exceptions percolated through this function.
@@ -167,9 +169,11 @@ class stack_alloc {
* @return A pointer to the allocated memory.
*/
inline void* alloc(size_t len) {
+ size_t pad = len % 8 == 0 ? 0 : 8 - len % 8;
+
// Typically, just return and increment the next location.
char* result = next_loc_;
- next_loc_ += len;
+ next_loc_ += len + pad;
// Occasionally, we have to switch blocks.
if (unlikely(next_loc_ >= cur_block_end_)) {
result = move_to_next_block(len);
diff --git a/test/unit/math/memory/stack_alloc_test.cpp b/test/unit/math/memory/stack_alloc_test.cpp
index f4e244afcae..b395df387e9 100644
--- a/test/unit/math/memory/stack_alloc_test.cpp
+++ b/test/unit/math/memory/stack_alloc_test.cpp
@@ -91,6 +91,15 @@ TEST(stack_alloc, alloc) {
allocator.recover_all();
}
+TEST(stack_alloc, alloc_aligned) {
+ stan::math::stack_alloc allocator;
+ int* x = allocator.alloc_array(3);
+
+ double* y = allocator.alloc_array(4);
+ EXPECT_TRUE(stan::math::is_aligned(y, 8));
+ allocator.recover_all();
+}
+
TEST(stack_alloc, in_stack) {
stan::math::stack_alloc allocator;
@@ -113,7 +122,11 @@ TEST(stack_alloc, in_stack_second_block) {
char* y = allocator.alloc_array(1);
EXPECT_TRUE(allocator.in_stack(x));
EXPECT_TRUE(allocator.in_stack(y));
- EXPECT_FALSE(allocator.in_stack(y + 1));
+ // effect of padding
+ EXPECT_TRUE(allocator.in_stack(y + 1));
+ EXPECT_TRUE(allocator.in_stack(y + 7));
+
+ EXPECT_FALSE(allocator.in_stack(y + 8));
allocator.recover_all();
EXPECT_FALSE(allocator.in_stack(x));