set CHANGE add optional destructor function as parameter of ly_set_rm* functions
diff --git a/src/context.c b/src/context.c
index 565ee91..45be465 100644
--- a/src/context.c
+++ b/src/context.c
@@ -141,7 +141,7 @@
 
     if (index >= 0) {
         /* remove specific search directory */
-        return ly_set_rm_index(&ctx->search_paths, index);
+        return ly_set_rm_index(&ctx->search_paths, index, free);
     } else {
         /* remove them all */
         ly_set_erase(&ctx->search_paths, free);
diff --git a/src/set.c b/src/set.c
index 7cfda31..7e567eb 100644
--- a/src/set.c
+++ b/src/set.c
@@ -162,11 +162,14 @@
 }
 
 API LY_ERR
-ly_set_rm_index(struct ly_set *set, unsigned int index)
+ly_set_rm_index(struct ly_set *set, unsigned int index, void (*destructor)(void *obj))
 {
     LY_CHECK_ARG_RET(NULL, set, LY_EINVAL);
-    LY_CHECK_ERR_RET(((index + 1) > set->count), LOGARG(NULL, index), LY_EINVAL);
+    LY_CHECK_ERR_RET(index >= set->count, LOGARG(NULL, index), LY_EINVAL);
 
+    if (destructor) {
+        destructor(set->objs[index]);
+    }
     if (index == set->count - 1) {
         /* removing last item in set */
         set->objs[index] = NULL;
@@ -181,7 +184,7 @@
 }
 
 API LY_ERR
-ly_set_rm(struct ly_set *set, void *object)
+ly_set_rm(struct ly_set *set, void *object, void (*destructor)(void *obj))
 {
     unsigned int i;
 
@@ -195,6 +198,6 @@
     }
     LY_CHECK_ERR_RET((i == set->count), LOGARG(NULL, object), LY_EINVAL); /* object is not in set */
 
-    return ly_set_rm_index(set, i);
+    return ly_set_rm_index(set, i, destructor);
 }
 
diff --git a/src/set.h b/src/set.h
index e226a5c..5834b8c 100644
--- a/src/set.h
+++ b/src/set.h
@@ -130,9 +130,10 @@
  *
  * @param[in] set Set from which the \p node will be removed.
  * @param[in] obejct The object to be removed from the \p set.
+ * @param[in] destructor Optional function to free the objects being removed.
  * @return LY_ERR return value.
  */
-LY_ERR ly_set_rm(struct ly_set *set, void *object);
+LY_ERR ly_set_rm(struct ly_set *set, void *object, void (*destructor)(void *obj));
 
 /**
  * @brief Remove an object on the specific set index.
@@ -142,9 +143,10 @@
  *
  * @param[in] set Set from which a node will be removed.
  * @param[in] index Index of the object to remove in the \p set.
+ * @param[in] destructor Optional function to free the objects being removed.
  * @return LY_ERR return value.
  */
-LY_ERR ly_set_rm_index(struct ly_set *set, unsigned int index);
+LY_ERR ly_set_rm_index(struct ly_set *set, unsigned int index, void (*destructor)(void *obj));
 
 /**
  * @brief Free the ::ly_set data. If the destructor is not provided, it frees only the set structure
diff --git a/tests/src/set.c b/tests/src/set.c
index 668434e..a6c53c4 100644
--- a/tests/src/set.c
+++ b/tests/src/set.c
@@ -123,16 +123,16 @@
     assert_int_equal(0, ly_set_merge(&set, NULL, 0, NULL));
     assert_string_equal(logbuf, "Invalid argument src (ly_set_merge()).");
 
-    assert_int_equal(LY_EINVAL, ly_set_rm_index(NULL, 0));
+    assert_int_equal(LY_EINVAL, ly_set_rm_index(NULL, 0, NULL));
     assert_string_equal(logbuf, "Invalid argument set (ly_set_rm_index()).");
-    assert_int_equal(LY_EINVAL, ly_set_rm_index(&set, 1));
+    assert_int_equal(LY_EINVAL, ly_set_rm_index(&set, 1, NULL));
     assert_string_equal(logbuf, "Invalid argument index (ly_set_rm_index()).");
 
-    assert_int_equal(LY_EINVAL, ly_set_rm(NULL, NULL));
+    assert_int_equal(LY_EINVAL, ly_set_rm(NULL, NULL, NULL));
     assert_string_equal(logbuf, "Invalid argument set (ly_set_rm()).");
-    assert_int_equal(LY_EINVAL, ly_set_rm(&set, NULL));
+    assert_int_equal(LY_EINVAL, ly_set_rm(&set, NULL, NULL));
     assert_string_equal(logbuf, "Invalid argument object (ly_set_rm()).");
-    assert_int_equal(LY_EINVAL, ly_set_rm(&set, &state));
+    assert_int_equal(LY_EINVAL, ly_set_rm(&set, &state, NULL));
     assert_string_equal(logbuf, "Invalid argument object (ly_set_rm()).");
 }
 
@@ -256,40 +256,40 @@
 
     /* fill the set */
     assert_int_equal(0, ly_set_add(&set, "string1", 0));
-    assert_int_equal(1, ly_set_add(&set, "string2", 0));
+    assert_int_equal(1, ly_set_add(&set, strdup("string2"), 0));
     assert_int_equal(2, ly_set_add(&set, "string3", 0));
 
     /* remove by index ... */
     /* ... in the middle ... */
-    assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1));
+    assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, free));
     assert_int_equal(2, set.count);
     assert_string_not_equal("string2", set.objs[0]);
     assert_string_not_equal("string2", set.objs[1]);
     /* ... last .. */
-    assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1));
+    assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, NULL));
     assert_int_equal(1, set.count);
     assert_string_not_equal("string3", set.objs[0]);
     /* ... first .. */
-    assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 0));
+    assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 0, NULL));
     assert_int_equal(0, set.count);
 
     /* fill the set */
     assert_int_equal(0, ly_set_add(&set, str1 = "string1", 0));
     assert_int_equal(1, ly_set_add(&set, str2 = "string2", 0));
-    assert_int_equal(2, ly_set_add(&set, str3 = "string3", 0));
+    assert_int_equal(2, ly_set_add(&set, str3 = strdup("string3"), 0));
 
     /* remove by pointer ... */
     /* ... in the middle ... */
-    assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str2));
+    assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str2, NULL));
     assert_int_equal(2, set.count);
     assert_string_not_equal("string2", set.objs[0]);
     assert_string_not_equal("string2", set.objs[1]);
-    /* ... last .. */
-    assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str3));
+    /* ... last (with destructor) .. */
+    assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str3, free));
     assert_int_equal(1, set.count);
     assert_string_not_equal("string3", set.objs[0]);
     /* ... first .. */
-    assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str1));
+    assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str1, NULL));
     assert_int_equal(0, set.count);
 
     /* cleanup */