diff --git a/examples/main.c b/examples/main.c
index be1ed7c192458fb08215035694bdb2a843400933..9cda03c14c364974a18e36c84e60227a01970dd5 100644
--- a/examples/main.c
+++ b/examples/main.c
@@ -611,6 +611,10 @@ int main(int argc, char *argv[]) {
     error("call to MPI_Finalize failed with error %i.", res);
 #endif
 
+  /* Clean everything */
+  engine_clean(&e);
+  free(params);
+
   /* Say goodbye. */
   if (myrank == 0) message("done. Bye.");
 
diff --git a/src/cell.c b/src/cell.c
index ddcf8defaf8a38fe35ae9798bb33db439f4f5ce4..2796a8933e1fedc2522c833570558adda369140b 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -707,3 +707,15 @@ void cell_clean_links(struct cell *c, void *data) {
   c->force = NULL;
   c->nr_force = 0;
 }
+
+/**
+ * @brief Frees up the memory allocated for this #cell
+ */
+void cell_clean(struct cell *c) {
+
+  free(c->sort);
+
+  /* Recurse */
+  for (int k = 0; k < 8; k++)
+    if (c->progeny[k]) cell_clean(c->progeny[k]);
+}
diff --git a/src/cell.h b/src/cell.h
index b9e060050827e6e0bbd62c87024bbf066d3807f8..a14d94d50ce6a4d2d25e7e6005c035cb22a3720d 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -197,5 +197,6 @@ void cell_init_parts(struct cell *c, void *data);
 void cell_init_gparts(struct cell *c, void *data);
 void cell_convert_hydro(struct cell *c, void *data);
 void cell_clean_links(struct cell *c, void *data);
+void cell_clean(struct cell *c);
 
 #endif /* SWIFT_CELL_H */
diff --git a/src/engine.c b/src/engine.c
index 6609f7f0d53453c6649a8089d2b656f555e00f75..b33850be9415f30f6c0ac38e70a74a7d239b791e 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -2864,20 +2864,22 @@ void engine_init(struct engine *e, struct space *s,
 
   if (verbose && with_aff) message("Affinity at entry: %s", buf);
 
-  int *cpuid = malloc(nr_affinity_cores * sizeof(int));
+  int *cpuid = NULL;
   cpu_set_t cpuset;
 
-  int skip = 0;
-  for (int k = 0; k < nr_affinity_cores; k++) {
-    int c;
-    for (c = skip; c < CPU_SETSIZE && !CPU_ISSET(c, entry_affinity); ++c)
-      ;
-    cpuid[k] = c;
-    skip = c + 1;
-  }
-
   if (with_aff) {
 
+    cpuid = malloc(nr_affinity_cores * sizeof(int));
+
+    int skip = 0;
+    for (int k = 0; k < nr_affinity_cores; k++) {
+      int c;
+      for (c = skip; c < CPU_SETSIZE && !CPU_ISSET(c, entry_affinity); ++c)
+        ;
+      cpuid[k] = c;
+      skip = c + 1;
+    }
+
 #if defined(HAVE_LIBNUMA) && defined(_GNU_SOURCE)
     if ((policy & engine_policy_cputight) != engine_policy_cputight) {
 
@@ -3176,8 +3178,8 @@ void engine_init(struct engine *e, struct space *s,
 #if defined(HAVE_SETAFFINITY)
   if (with_aff) {
     free(cpuid);
-    free(buf);
   }
+  free(buf);
 #endif
 
   /* Wait for the runner threads to be in place. */
@@ -3241,3 +3243,14 @@ void engine_compute_next_snapshot_time(struct engine *e) {
       message("Next output time set to t=%e.", next_snapshot_time);
   }
 }
+
+/**
+ * @brief Frees up the memory allocated for this #engine
+ */
+void engine_clean(struct engine *e) {
+
+  free(e->snapshotUnits);
+  free(e->links);
+  scheduler_clean(&e->sched);
+  space_clean(e->s);
+}
diff --git a/src/engine.h b/src/engine.h
index 9ec42cd3654d012fc42adda021cab7bb5a81dd58..d708198c32b67c5118bbd7f4676f1ea0fe821c7d 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -239,5 +239,6 @@ void engine_print_policy(struct engine *e);
 int engine_is_done(struct engine *e);
 void engine_pin();
 void engine_unpin();
+void engine_clean(struct engine *e);
 
 #endif /* SWIFT_ENGINE_H */
diff --git a/src/queue.c b/src/queue.c
index 9883d77e66421eda6093331e0c9a8f6ac0155ded..38f8620fdc75d744df31513792e96323dbf83647 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -296,3 +296,9 @@ struct task *queue_gettask(struct queue *q, const struct task *prev,
   /* Take the money and run. */
   return res;
 }
+
+void queue_clean(struct queue *q) {
+
+  free(q->tid);
+  free(q->tid_incoming);
+}
diff --git a/src/queue.h b/src/queue.h
index 5878866c890f53f22c3deaac7fe9b6bba75d499e..c0a2fb1da6e6e3cbea813a0ef53841084ab0f933 100644
--- a/src/queue.h
+++ b/src/queue.h
@@ -64,5 +64,6 @@ struct task *queue_gettask(struct queue *q, const struct task *prev,
                            int blocking);
 void queue_init(struct queue *q, struct task *tasks);
 void queue_insert(struct queue *q, struct task *t);
+void queue_clean(struct queue *q);
 
 #endif /* SWIFT_QUEUE_H */
diff --git a/src/runner.c b/src/runner.c
index 63243ab66d24a2efc045e19e866e24b7a0f4868c..01762dda28aaa8f1fa3e240824761d90c9f8f702 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -428,7 +428,6 @@ void runner_do_ghost(struct runner *r, struct cell *c) {
   struct xpart *xp, *xparts = c->xparts;
   struct cell *finger;
   int redo, count = c->count;
-  int *pid;
   float h_corr;
   const int ti_current = r->e->ti_current;
   const double timeBase = r->e->timeBase;
@@ -450,8 +449,9 @@ void runner_do_ghost(struct runner *r, struct cell *c) {
   }
 
   /* Init the IDs that have to be updated. */
-  if ((pid = (int *)alloca(sizeof(int) * count)) == NULL)
-    error("Call to alloca failed.");
+  int *pid = NULL;
+  if ((pid = malloc(sizeof(int) * count)) == NULL)
+    error("Can't allocate memory for pid.");
   for (int k = 0; k < count; k++) pid[k] = k;
 
   /* While there are particles that need to be updated... */
@@ -572,6 +572,9 @@ void runner_do_ghost(struct runner *r, struct cell *c) {
   if (count)
     message("Smoothing length failed to converge on %i particles.", count);
 
+  /* Be clean */
+  free(pid);
+
   TIMER_TOC(timer_do_ghost);
 }
 
diff --git a/src/runner_doiact.h b/src/runner_doiact.h
index 7d98c76490e3cc3f87fd2e54902273f2b7f3fa63..db439671ff5fee56c086444ddaa8268571c80a15 100644
--- a/src/runner_doiact.h
+++ b/src/runner_doiact.h
@@ -950,8 +950,8 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) {
     sortdt_i = sort_i;
     countdt_i = count_i;
   } else if (ci->ti_end_min <= ti_current) {
-    if ((sortdt_i = (struct entry *)alloca(sizeof(struct entry) * count_i)) ==
-        NULL)
+    if (posix_memalign((void *)&sortdt_i, VEC_SIZE * sizeof(float),
+                       sizeof(struct entry) * count_i) != 0)
       error("Failed to allocate dt sortlists.");
     for (int k = 0; k < count_i; k++)
       if (parts_i[sort_i[k].i].ti_end <= ti_current) {
@@ -963,8 +963,8 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) {
     sortdt_j = sort_j;
     countdt_j = count_j;
   } else if (cj->ti_end_min <= ti_current) {
-    if ((sortdt_j = (struct entry *)alloca(sizeof(struct entry) * count_j)) ==
-        NULL)
+    if (posix_memalign((void *)&sortdt_j, VEC_SIZE * sizeof(float),
+                       sizeof(struct entry) * count_j) != 0)
       error("Failed to allocate dt sortlists.");
     for (int k = 0; k < count_j; k++)
       if (parts_j[sort_j[k].i].ti_end <= ti_current) {
@@ -1270,6 +1270,11 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) {
       IACT(r2q2[k], &dxq2[3 * k], hiq2[k], hjq2[k], piq2[k], pjq2[k]);
 #endif
 
+  if (ci->ti_end_max > ti_current && ci->ti_end_min <= ti_current)
+    free(sortdt_i);
+  if (cj->ti_end_max > ti_current && cj->ti_end_min <= ti_current)
+    free(sortdt_j);
+
   TIMER_TOC(TIMER_DOPAIR);
 }
 
@@ -1309,7 +1314,8 @@ void DOSELF1(struct runner *r, struct cell *restrict c) {
   /* Set up indt. */
   int *indt = NULL;
   int countdt = 0, firstdt = 0;
-  if ((indt = (int *)alloca(sizeof(int) * count)) == NULL)
+  if (posix_memalign((void *)&indt, VEC_SIZE * sizeof(int),
+                     count * sizeof(int)) != 0)
     error("Failed to allocate indt.");
   for (int k = 0; k < count; k++)
     if (parts[k].ti_end <= ti_current) {
@@ -1499,6 +1505,8 @@ void DOSELF1(struct runner *r, struct cell *restrict c) {
       IACT(r2q2[k], &dxq2[3 * k], hiq2[k], hjq2[k], piq2[k], pjq2[k]);
 #endif
 
+  free(indt);
+
   TIMER_TOC(TIMER_DOSELF);
 }
 
@@ -1538,7 +1546,8 @@ void DOSELF2(struct runner *r, struct cell *restrict c) {
   /* Set up indt. */
   int *indt = NULL;
   int countdt = 0, firstdt = 0;
-  if ((indt = (int *)alloca(sizeof(int) * count)) == NULL)
+  if (posix_memalign((void *)&indt, VEC_SIZE * sizeof(int),
+                     count * sizeof(int)) != 0)
     error("Failed to allocate indt.");
   for (int k = 0; k < count; k++)
     if (parts[k].ti_end <= ti_current) {
@@ -1701,6 +1710,8 @@ void DOSELF2(struct runner *r, struct cell *restrict c) {
       IACT(r2q2[k], &dxq2[3 * k], hiq2[k], hjq2[k], piq2[k], pjq2[k]);
 #endif
 
+  free(indt);
+
   TIMER_TOC(TIMER_DOSELF);
 }
 
diff --git a/src/scheduler.c b/src/scheduler.c
index d760545ea74ddb288887a800c692136682f70d12..2c47851b36a1ca3b547d32d56ef810381a030054 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -1298,3 +1298,16 @@ void scheduler_do_rewait(struct task *t_begin, struct task *t_end,
     }
   }
 }
+
+/**
+ * @brief Frees up the memory allocated for this #scheduler
+ */
+void scheduler_clean(struct scheduler *s) {
+
+  free(s->tasks);
+  free(s->tasks_ind);
+  free(s->unlocks);
+  free(s->unlock_ind);
+  for (int i = 0; i < s->nr_queues; ++i) queue_clean(&s->queues[i]);
+  free(s->queues);
+}
diff --git a/src/scheduler.h b/src/scheduler.h
index 62af23152e7e2d2bc68e0cc4d7122f4dd0483aa1..1822f54a87b199c8eff72ec64745bcf69be279aa 100644
--- a/src/scheduler.h
+++ b/src/scheduler.h
@@ -124,5 +124,6 @@ void scheduler_dump_queue(struct scheduler *s);
 void scheduler_print_tasks(const struct scheduler *s, const char *fileName);
 void scheduler_do_rewait(struct task *t_begin, struct task *t_end,
                          unsigned int mask, unsigned int submask);
+void scheduler_clean(struct scheduler *s);
 
 #endif /* SWIFT_SCHEDULER_H */
diff --git a/src/space.c b/src/space.c
index d251139ee4308318d16116eb22683f362b6235b2..ea652f7f9b918e7f4f1ebe0a81e6604765691eb1 100644
--- a/src/space.c
+++ b/src/space.c
@@ -1558,3 +1558,15 @@ void space_link_cleanup(struct space *s) {
   /* Recursively apply the cell link cleaning routine */
   space_map_cells_pre(s, 1, cell_clean_links, NULL);
 }
+
+/**
+ * @brief Frees up the memory allocated for this #space
+ */
+void space_clean(struct space *s) {
+
+  for (int i = 0; i < s->nr_cells; ++i) cell_clean(&s->cells[i]);
+  free(s->cells);
+  free(s->parts);
+  free(s->xparts);
+  free(s->gparts);
+}
diff --git a/src/space.h b/src/space.h
index dd182e2cdbfb427d086f763bddbd915f15ada514..a859ff5cb0497276ba5ae6dcec6a47d0ca5d7398 100644
--- a/src/space.h
+++ b/src/space.h
@@ -160,5 +160,6 @@ void space_do_split(struct space *s, struct cell *c);
 void space_do_parts_sort();
 void space_do_gparts_sort();
 void space_link_cleanup(struct space *s);
+void space_clean(struct space *s);
 
 #endif /* SWIFT_SPACE_H */