add new option CS_OPT_MEM for cs_option(): this enable user-defined dynamic memory management. idea proposed by Pancake
diff --git a/cs.c b/cs.c
index ded7cff..fca0f12 100644
--- a/cs.c
+++ b/cs.c
@@ -19,6 +19,10 @@
 
 unsigned int all_arch = 0;
 
+malloc_t my_malloc = malloc;
+calloc_t my_calloc = calloc;
+realloc_t my_realloc = realloc;
+free_t my_free = free;
 
 unsigned int cs_version(int *major, int *minor)
 {
@@ -78,7 +82,7 @@
 {
 	cs_struct *ud;
 
-	ud = calloc(1, sizeof(*ud));
+	ud = my_calloc(1, sizeof(*ud));
 	if (!ud) {
 		// memory insufficient
 		return CS_ERR_MEM;
@@ -117,7 +121,7 @@
 		case CS_ARCH_MIPS:
 		case CS_ARCH_ARM64:
 		case CS_ARCH_PPC:
-			free(ud->printer_info);
+			my_free(ud->printer_info);
 			break;
 		default:	// unsupported architecture
 			return CS_ERR_HANDLE;
@@ -127,7 +131,7 @@
 		arch_destroy[ud->arch](ud);
 
 	memset(ud, 0, sizeof(*ud));
-	free(ud);
+	my_free(ud);
 
 	return CS_ERR_OK;
 }
@@ -191,6 +195,19 @@
 
 cs_err cs_option(csh ud, cs_opt_type type, size_t value)
 {
+	// cs_option() can be called with NULL handle just for CS_OPT_MEM
+	// This is supposed to be executed before all other APIs (even cs_open())
+	if (type == CS_OPT_MEM) {
+		cs_opt_mem *mem = (cs_opt_mem *)value;
+
+		my_malloc = mem->malloc;
+		my_calloc = mem->calloc;
+		my_realloc = mem->realloc;
+		my_free = mem->free;
+
+		return CS_ERR_OK;
+	}
+
 	cs_struct *handle = (cs_struct *)(uintptr_t)ud;
 	if (!handle)
 		return CS_ERR_CSH;
@@ -243,7 +260,7 @@
 				mci.flat_insn.address = offset;
 				mci.flat_insn.size = insn_size;
 				// allocate memory for @detail pointer
-				insn_cache[f].detail = calloc(1, sizeof(cs_detail));
+				insn_cache[f].detail = my_calloc(1, sizeof(cs_detail));
 			}
 
 			handle->printer(&mci, &ss, handle->printer_info);
@@ -255,9 +272,9 @@
 			if (f == ARR_SIZE(insn_cache)) {
 				// resize total to contain newly disasm insns
 				total_size += sizeof(insn_cache);
-				void *tmp = realloc(total, total_size);
+				void *tmp = my_realloc(total, total_size);
 				if (tmp == NULL) {	// insufficient memory
-					free(total);
+					my_free(total);
 					handle->errnum = CS_ERR_MEM;
 					return 0;
 				}
@@ -284,9 +301,9 @@
 
 	if (f) {
 		// resize total to contain newly disasm insns
-		void *tmp = realloc(total, total_size + f * sizeof(insn_cache[0]));
+		void *tmp = my_realloc(total, total_size + f * sizeof(insn_cache[0]));
 		if (tmp == NULL) {	// insufficient memory
-			free(total);
+			my_free(total);
 			handle->errnum = CS_ERR_MEM;
 			return 0;
 		}
@@ -306,10 +323,10 @@
 
 	// free all detail pointers
 	for (i = 0; i < count; i++)
-		free(insn[i].detail);
+		my_free(insn[i].detail);
 
 	// then free pointer to cs_insn array
-	free(insn);
+	my_free(insn);
 }
 
 // return friendly name of regiser in a string