diff --git a/configure.ac b/configure.ac
index 6162bc7c173ba2d913be3c447b729b0e37e1dd36..d8cd381b359335486f7e2ea517bb08b65103de47 100644
--- a/configure.ac
+++ b/configure.ac
@@ -369,6 +369,33 @@ if test "$enable_san" = "yes"; then
    fi
 fi
 
+# Add the undefined sanitizer option to flags. Only useful for GCC
+# version 4.9 and later and clang to detected undefined code behaviour
+# such as integer overflow and memory alignment issues.
+AC_ARG_ENABLE([undefined-sanitizer],
+   [AS_HELP_STRING([--enable-undefined-sanitizer],
+     [Enable detection of code that causes undefined behaviour @<:@no/yes@:>@]
+   )],
+   [enable_ubsan="$enableval"],
+   [enable_ubsan="no"]
+)
+
+if test "$enable_ubsan" = "yes"; then
+   if test "$ax_cv_c_compiler_vendor" = "gnu"; then
+      AX_COMPARE_VERSION( $ax_cv_c_compiler_version, [ge], [4.9.0],
+                          [enable_ubsan="yes"], [enable_ubsan="no"] )
+   elif test "$ax_cv_c_compiler_vendor" = "clang"; then
+      AX_COMPARE_VERSION( $ax_cv_c_compiler_version, [ge], [3.7.0],
+                          [enable_ubsan="yes"], [enable_ubsan="no"] )
+   fi
+   if test "$enable_ubsan" = "yes"; then
+      CFLAGS="$CFLAGS -fsanitize=undefined"
+      AC_MSG_RESULT([added undefined sanitizer support])
+   else
+      AC_MSG_WARN([Compiler does not support undefined sanitizer option])
+   fi
+fi
+
 # Autoconf stuff.
 AC_PROG_INSTALL
 AC_PROG_MAKE_SET
diff --git a/src/engine.c b/src/engine.c
index ee41d03ceffec5b401693802910a0287adce48dd..4c55cb451c450606b308c54df3417b85f969a97e 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -1482,9 +1482,9 @@ void engine_exchange_cells(struct engine *e) {
   }
 
   /* Allocate the pcells. */
-  struct pcell *pcells;
-  if ((pcells = (struct pcell *)malloc(sizeof(struct pcell) * count_out)) ==
-      NULL)
+  struct pcell *pcells = NULL;
+  if (posix_memalign((void **)&pcells, SWIFT_CACHE_ALIGNMENT,
+                     sizeof(struct pcell) * count_out) != 0)
     error("Failed to allocate pcell buffer.");
 
   /* Pack the cells. */
@@ -2048,11 +2048,14 @@ void engine_exchange_proxy_multipoles(struct engine *e) {
   }
 
   /* Allocate the buffers for the packed data */
-  struct gravity_tensors *buffer_send =
-      malloc(sizeof(struct gravity_tensors) * count_send);
-  struct gravity_tensors *buffer_recv =
-      malloc(sizeof(struct gravity_tensors) * count_recv);
-  if (buffer_send == NULL || buffer_recv == NULL)
+  struct gravity_tensors *buffer_send = NULL;
+  if (posix_memalign((void **)&buffer_send, SWIFT_CACHE_ALIGNMENT,
+                     count_send * sizeof(struct gravity_tensors)) != 0)
+    error("Unable to allocate memory for multipole transactions");
+
+  struct gravity_tensors *buffer_recv = NULL;
+  if (posix_memalign((void **)&buffer_recv, SWIFT_CACHE_ALIGNMENT,
+                     count_recv * sizeof(struct gravity_tensors)) != 0)
     error("Unable to allocate memory for multipole transactions");
 
   /* Also allocate the MPI requests */
@@ -4893,8 +4896,10 @@ void engine_split(struct engine *e, struct partition *initial_partition) {
       posix_memalign((void **)&xparts_new, xpart_align,
                      sizeof(struct xpart) * s->size_parts) != 0)
     error("Failed to allocate new part data.");
-  memcpy(parts_new, s->parts, sizeof(struct part) * s->nr_parts);
-  memcpy(xparts_new, s->xparts, sizeof(struct xpart) * s->nr_parts);
+  if (s->nr_parts > 0) {
+    memcpy(parts_new, s->parts, sizeof(struct part) * s->nr_parts);
+    memcpy(xparts_new, s->xparts, sizeof(struct xpart) * s->nr_parts);
+  }
   free(s->parts);
   free(s->xparts);
   s->parts = parts_new;
@@ -4913,7 +4918,8 @@ void engine_split(struct engine *e, struct partition *initial_partition) {
   if (posix_memalign((void **)&sparts_new, spart_align,
                      sizeof(struct spart) * s->size_sparts) != 0)
     error("Failed to allocate new spart data.");
-  memcpy(sparts_new, s->sparts, sizeof(struct spart) * s->nr_sparts);
+  if (s->nr_sparts > 0)
+    memcpy(sparts_new, s->sparts, sizeof(struct spart) * s->nr_sparts);
   free(s->sparts);
   s->sparts = sparts_new;
 
@@ -4930,7 +4936,8 @@ void engine_split(struct engine *e, struct partition *initial_partition) {
   if (posix_memalign((void **)&gparts_new, gpart_align,
                      sizeof(struct gpart) * s->size_gparts) != 0)
     error("Failed to allocate new gpart data.");
-  memcpy(gparts_new, s->gparts, sizeof(struct gpart) * s->nr_gparts);
+  if (s->nr_gparts > 0)
+    memcpy(gparts_new, s->gparts, sizeof(struct gpart) * s->nr_gparts);
   free(s->gparts);
   s->gparts = gparts_new;
 
@@ -5450,8 +5457,8 @@ void engine_init(struct engine *e, struct space *s,
       parser_get_opt_param_int(params, "Scheduler:mpi_message_limit", 4) * 1024;
 
   /* Allocate and init the threads. */
-  if ((e->runners = (struct runner *)malloc(sizeof(struct runner) *
-                                            e->nr_threads)) == NULL)
+  if (posix_memalign((void **)&e->runners, SWIFT_CACHE_ALIGNMENT,
+                     e->nr_threads * sizeof(struct runner)) != 0)
     error("Failed to allocate threads array.");
   for (int k = 0; k < e->nr_threads; k++) {
     e->runners[k].id = k;