diff --git a/py/gc.c b/py/gc.c
index 0c9c5608605f99b76b1df742bb17c4cdd178ab78..4a3d1dabee9caa352974565ccb4135d77a932fef 100644
--- a/py/gc.c
+++ b/py/gc.c
@@ -20,7 +20,6 @@ typedef unsigned char byte;
 #define STACK_SIZE (64) // tunable; minimum is 1
 
 static byte *gc_alloc_table_start;
-static byte *gc_alloc_table_end;
 static machine_uint_t gc_alloc_table_byte_len;
 static machine_uint_t *gc_pool_start;
 static machine_uint_t *gc_pool_end;
@@ -29,31 +28,6 @@ static int gc_stack_overflow;
 static machine_uint_t gc_stack[STACK_SIZE];
 static machine_uint_t *gc_sp;
 
-// TODO waste less memory; currently requires that all entries in alloc_table have a corresponding block in pool
-void gc_init(void *start, void *end) {
-    // align end pointer on block boundary
-    end = (void*)((machine_uint_t)end & (~(BYTES_PER_BLOCK - 1)));
-
-    // calculate parameters for GC
-    machine_uint_t total_word_len = (machine_uint_t*)end - (machine_uint_t*)start;
-    gc_alloc_table_byte_len = total_word_len * BYTES_PER_WORD / (1 + BITS_PER_BYTE / 2 * BYTES_PER_BLOCK);
-    gc_alloc_table_start = (byte*)start;
-    gc_alloc_table_end = gc_alloc_table_start + gc_alloc_table_byte_len;
-    machine_uint_t gc_pool_block_len = gc_alloc_table_byte_len * BITS_PER_BYTE / 2;
-    machine_uint_t gc_pool_word_len = gc_pool_block_len * WORDS_PER_BLOCK;
-    gc_pool_start = (machine_uint_t*)end - gc_pool_word_len;
-    gc_pool_end = end;
-
-    // clear ATBs
-    memset(gc_alloc_table_start, 0, gc_alloc_table_byte_len);
-
-    /*
-    printf("GC layout:\n");
-    printf("  alloc table at %p, length %u bytes\n", gc_alloc_table_start, gc_alloc_table_byte_len);
-    printf("  pool at %p, length %u blocks = %u words = %u bytes\n", gc_pool_start, gc_pool_block_len, gc_pool_word_len, gc_pool_word_len * BYTES_PER_WORD);
-    */
-}
-
 // ATB = allocation table byte
 // 0b00 = FREE -- free block
 // 0b01 = HEAD -- head of a chain of blocks
@@ -88,6 +62,37 @@ void gc_init(void *start, void *end) {
 #define PTR_FROM_BLOCK(block) (((block) * BYTES_PER_BLOCK + (machine_uint_t)gc_pool_start))
 #define ATB_FROM_BLOCK(bl) ((bl) / BLOCKS_PER_ATB)
 
+// TODO waste less memory; currently requires that all entries in alloc_table have a corresponding block in pool
+void gc_init(void *start, void *end) {
+    // align end pointer on block boundary
+    end = (void*)((machine_uint_t)end & (~(BYTES_PER_BLOCK - 1)));
+
+    // calculate parameters for GC
+    machine_uint_t total_word_len = (machine_uint_t*)end - (machine_uint_t*)start;
+    gc_alloc_table_byte_len = total_word_len * BYTES_PER_WORD / (1 + BITS_PER_BYTE / 2 * BYTES_PER_BLOCK);
+    gc_alloc_table_start = (byte*)start;
+    machine_uint_t gc_pool_block_len = gc_alloc_table_byte_len * BITS_PER_BYTE / 2;
+    machine_uint_t gc_pool_word_len = gc_pool_block_len * WORDS_PER_BLOCK;
+    gc_pool_start = (machine_uint_t*)end - gc_pool_word_len;
+    gc_pool_end = end;
+
+    // clear ATBs
+    memset(gc_alloc_table_start, 0, gc_alloc_table_byte_len);
+
+    // allocate first block because gc_pool_start points there and it will never
+    // be freed, so allocating 1 block with null pointers will minimise memory loss
+    ATB_FREE_TO_HEAD(0);
+    for (int i = 0; i < WORDS_PER_BLOCK; i++) {
+        gc_pool_start[i] = 0;
+    }
+
+    /*
+    printf("GC layout:\n");
+    printf("  alloc table at %p, length %u bytes\n", gc_alloc_table_start, gc_alloc_table_byte_len);
+    printf("  pool at %p, length %u blocks = %u words = %u bytes\n", gc_pool_start, gc_pool_block_len, gc_pool_word_len, gc_pool_word_len * BYTES_PER_WORD);
+    */
+}
+
 #define VERIFY_PTR(ptr) ( \
         (ptr & (BYTES_PER_BLOCK - 1)) == 0          /* must be aligned on a block */ \
         && ptr >= (machine_uint_t)gc_pool_start     /* must be above start of pool */ \
diff --git a/py/lexer.c b/py/lexer.c
index 9ab0641967003b4ba3b66fb51b2e7be5eda07472..88bc0a1aae2212e4c76c05971bc873ce4f0acdab 100644
--- a/py/lexer.c
+++ b/py/lexer.c
@@ -635,6 +635,7 @@ void py_lexer_free(py_lexer_t *lex) {
         if (lex->stream_close) {
             lex->stream_close(lex->stream_data);
         }
+        vstr_clear(&lex->vstr);
         m_free(lex);
     }
 }