schema CHANGE redesign Sized arrays to be usable in a more simple way
diff --git a/src/common.h b/src/common.h
index 380ec6e..c704ca8 100644
--- a/src/common.h
+++ b/src/common.h
@@ -276,21 +276,53 @@
 /**
  * @brief (Re-)Allocation of a ([sized array](@ref sizedarrays)).
  *
+ * Increases the size information.
+ *
  * @param[in] CTX libyang context for logging.
- * @param[in,out] ARRAY Pointer to the array to allocate/resize.
+ * @param[in,out] ARRAY Pointer to the array to allocate/resize. The size of the allocated
+ * space is counted from the type of the ARRAY, so do not provide placeholder void pointers.
  * @param[out] NEW_ITEM Returning pointer to the newly allocated record in the ARRAY.
  * @param[in] RETVAL Return value for the case of error (memory allocation failure).
  */
-#define LYSP_ARRAY_NEW_RET(CTX, ARRAY, NEW_ITEM, RETVAL) \
+#define LY_ARRAY_NEW_RET(CTX, ARRAY, NEW_ITEM, RETVAL) \
         if (!(ARRAY)) { \
             ARRAY = malloc(sizeof(uint32_t) + sizeof *(ARRAY)); \
             *((uint32_t*)(ARRAY)) = 1; \
         } else { \
-            ++(*((uint32_t*)(ARRAY))); \
-            ARRAY = ly_realloc(ARRAY, sizeof(uint32_t) + (*((uint32_t*)(ARRAY)) * sizeof *(ARRAY))); \
+            ++(*((uint32_t*)(ARRAY) - 1)); \
+            ARRAY = ly_realloc(((uint32_t*)(ARRAY) - 1), sizeof(uint32_t) + (*((uint32_t*)(ARRAY) - 1) * sizeof *(ARRAY))); \
             LY_CHECK_ERR_RET(!(ARRAY), LOGMEM(CTX), RETVAL); \
         } \
-        (NEW_ITEM) = (void*)((uint32_t*)((ARRAY) + *((uint32_t*)(ARRAY)) - 1) + 1); \
-        memset(NEW_ITEM, 0, sizeof *(NEW_ITEM));
+        ARRAY = (void*)((uint32_t*)(ARRAY) + 1); \
+        (NEW_ITEM) = &(ARRAY)[*((uint32_t*)(ARRAY) - 1) - 1]; \
+        memset(NEW_ITEM, 0, sizeof *(NEW_ITEM))
 
+/**
+ * @brief Allocate a ([sized array](@ref sizedarrays)) for the specified number of items.
+ *
+ * Does not set the size information, it is supposed to be incremented via ::LY_ARRAY_INCREMENT
+ * when the items are filled.
+ *
+ * @param[in] CTX libyang context for logging.
+ * @param[in,out] ARRAY Pointer to the array to create.
+ * @param[in] SIZE Number of items the array is supposed to hold. The size of the allocated
+ * space is then counted from the type of the ARRAY, so do not provide placeholder void pointers.
+ * @param[in] RETVAL Return value for the case of error (memory allocation failure).
+ */
+#define LY_ARRAY_CREATE_RET(CTX, ARRAY, SIZE, RETVAL) \
+        ARRAY = calloc(1, sizeof(uint32_t) + SIZE * sizeof *(ARRAY)); \
+        LY_CHECK_ERR_RET(!(ARRAY), LOGMEM(CTX), RETVAL); \
+        ARRAY = (void*)((uint32_t*)(ARRAY) + 1)
+
+#define LY_ARRAY_INCREMENT(ARRAY) \
+        ++(*((uint32_t*)(ARRAY) - 1))
+/**
+ * @brief Free the space allocated for the ([sized array](@ref sizedarrays)).
+ *
+ * The items inside the array are not freed.
+ *
+ * @param[in] ARRAY A ([sized array](@ref sizedarrays)) to be freed.
+ */
+#define LY_ARRAY_FREE(ARRAY) \
+        if (ARRAY){free((uint32_t*)(ARRAY) - 1);}
 #endif /* LY_COMMON_H_ */
diff --git a/src/libyang.h b/src/libyang.h
index bb93a74..060d49a 100644
--- a/src/libyang.h
+++ b/src/libyang.h
@@ -81,15 +81,15 @@
  * @section sizedarrays Sized Arrays
  *
  * The structure starts with 32bit number storing size of the array - the number of the items inside. The size is part of the
- * array to allocate it together with the array itself only when it is needed. This way the memory demands are decreased with
- * possibility to have "infinite" (32bit) array of items. Because of a known size, it is not terminated by any special byte
- * (sequence), so there is also no limit for specific content of the stored records (e.g. that first byte must not be NULL).
+ * array to have it allocated together with the array itself only when it is needed. However, the pointers to the array always
+ * points after the 32b number, so items can be accessed directly as for standard C arrays. Because of a known size (available
+ * via ::LY_ARRAY_SIZE macro), it is not terminated by any special byte (sequence), so there is also no limitation for specific
+ * content of the stored records (e.g. that first byte must not be NULL).
  *
- * Due to the structure, the records in the array cannot be accessed directly. There is a set of macros supposed to make
- * work with the arrays more easy.
+ * The sized arrays must be carefully freed (which should be done anyway only internally), since pointers to the sized arrays used
+ * in libyang structures, does not point to the beginning of the allocated space.
  *
  * - ::LY_ARRAY_SIZE
- * - ::LY_ARRAY_INDEX
  * - ::LY_ARRAY_FOR
  *
  * @section struct_lists Lists
diff --git a/src/parser_yang.c b/src/parser_yang.c
index f46b901..434073d 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -1036,7 +1036,7 @@
     struct lysp_ext_instance *e;
     enum yang_keyword kw;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *exts, e, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *exts, e, LY_EMEM);
 
     /* store name and insubstmt info */
     e->name = lydict_insert(ctx->ctx, ext_name, ext_name_len);
@@ -1299,7 +1299,7 @@
     enum yang_keyword kw;
     struct lysp_include *inc;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *includes, inc, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *includes, inc, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -1351,7 +1351,7 @@
     enum yang_keyword kw;
     struct lysp_import *imp;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, module->imports, imp, LY_EVALID);
+    LY_ARRAY_NEW_RET(ctx->ctx, module->imports, imp, LY_EVALID);
 
     /* get value */
     ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -1413,7 +1413,7 @@
     enum yang_keyword kw;
     struct lysp_revision *rev;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *revs, rev, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *revs, rev, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_STR_ARG, &word, &buf, &word_len);
@@ -1474,7 +1474,7 @@
     enum yang_keyword kw;
 
     /* allocate new pointer */
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *texts, item, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *texts, item, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, arg, &word, &buf, &word_len);
@@ -1679,7 +1679,7 @@
 {
     struct lysp_restr *restr;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *restrs, restr, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *restrs, restr, LY_EMEM);
 
     return parse_restr(ctx, data, restr_kw, restr);
 }
@@ -1980,7 +1980,7 @@
     enum yang_keyword kw;
     struct lysp_type_enum *enm;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *enums, enm, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *enums, enm, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_STR_ARG, &word, &buf, &word_len);
@@ -2226,7 +2226,7 @@
     enum yang_keyword kw;
     struct lysp_restr *restr;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *patterns, restr, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *patterns, restr, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_STR_ARG, &word, &buf, &word_len);
@@ -2353,7 +2353,7 @@
             break;
         case YANG_TYPE:
             {
-                LYSP_ARRAY_NEW_RET(ctx->ctx, type->types, nest_type, LY_EMEM);
+                LY_ARRAY_NEW_RET(ctx->ctx, type->types, nest_type, LY_EMEM);
             }
             ret = parse_type(ctx, data, nest_type);
             break;
@@ -2786,7 +2786,7 @@
     enum yang_keyword kw;
     struct lysp_refine *rf;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *refines, rf, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *refines, rf, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_STR_ARG, &word, &buf, &word_len);
@@ -2859,7 +2859,7 @@
     enum yang_keyword kw;
     struct lysp_tpdf *tpdf;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *typedefs, tpdf, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *typedefs, tpdf, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -3006,7 +3006,7 @@
     enum yang_keyword kw;
     struct lysp_action *act;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *actions, act, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *actions, act, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -3075,7 +3075,7 @@
     enum yang_keyword kw;
     struct lysp_notif *notif;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *notifs, notif, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *notifs, notif, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -3163,7 +3163,7 @@
     enum yang_keyword kw;
     struct lysp_grp *grp;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *groupings, grp, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *groupings, grp, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -3252,7 +3252,7 @@
     enum yang_keyword kw;
     struct lysp_augment *aug;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *augments, aug, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *augments, aug, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_STR_ARG, &word, &buf, &word_len);
@@ -3973,7 +3973,7 @@
     enum yang_keyword kw;
     struct lysp_ext *ex;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *extensions, ex, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *extensions, ex, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -4248,7 +4248,7 @@
     enum yang_keyword kw;
     struct lysp_deviation *dev;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *deviations, dev, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *deviations, dev, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_STR_ARG, &word, &buf, &word_len);
@@ -4306,7 +4306,7 @@
     enum yang_keyword kw;
     struct lysp_feature *feat;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *features, feat, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *features, feat, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
@@ -4361,7 +4361,7 @@
     enum yang_keyword kw;
     struct lysp_ident *ident;
 
-    LYSP_ARRAY_NEW_RET(ctx->ctx, *identities, ident, LY_EMEM);
+    LY_ARRAY_NEW_RET(ctx->ctx, *identities, ident, LY_EMEM);
 
     /* get value */
     ret = get_argument(ctx, data, Y_IDENTIF_ARG, &word, &buf, &word_len);
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 73c4fad..3960bb3 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -28,10 +28,10 @@
 #include "context.h"
 #include "tree_schema_internal.h"
 
-#define FREE_ARRAY(CTX, ARRAY, FUNC) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FUNC(CTX, LY_ARRAY_INDEX(ARRAY, c__), dict);}free(ARRAY);}
+#define FREE_ARRAY(CTX, ARRAY, FUNC) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FUNC(CTX, &ARRAY[c__], dict);}LY_ARRAY_FREE(ARRAY);}
 #define FREE_MEMBER(CTX, MEMBER, FUNC) if (MEMBER) {FUNC(CTX, MEMBER, dict);free(MEMBER);}
 #define FREE_STRING(CTX, STRING, DICT) if (DICT && STRING) {lydict_remove(CTX, STRING);}
-#define FREE_STRINGS(CTX, ARRAY, DICT) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FREE_STRING(CTX, *(LY_ARRAY_INDEX(ARRAY, c__, const char*)), DICT);}free(ARRAY);}
+#define FREE_STRINGS(CTX, ARRAY, DICT) {uint64_t c__; LY_ARRAY_FOR(ARRAY, c__){FREE_STRING(CTX, ARRAY[c__], DICT);}LY_ARRAY_FREE(ARRAY);}
 
 static void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp, int dict);
 static void lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node, int dict);
@@ -122,16 +122,7 @@
 lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident, int dict)
 {
     FREE_STRING(ctx, ident->name, dict);
-    //FREE_STRINGS(ctx, ident->iffeatures, 1);
-    {
-        uint64_t c__;
-        for (c__ = 0; ident->iffeatures && c__ < (*((uint32_t*)(ident->iffeatures))); ++c__) {
-            if (1 && ((void*)((uint32_t*)((ident->iffeatures) + c__) + 1))) {
-                lydict_remove(ctx, *((char**)((uint32_t*)((ident->iffeatures) + c__) + 1)));
-            };
-        }
-        free(ident->iffeatures);
-    }
+    FREE_STRINGS(ctx, ident->iffeatures, 1);
     FREE_STRINGS(ctx, ident->bases, dict);
     FREE_STRING(ctx, ident->dsc, dict);
     FREE_STRING(ctx, ident->ref, dict);
@@ -460,7 +451,7 @@
 static void
 lysc_iffeature_free(struct ly_ctx *UNUSED(ctx), struct lysc_iffeature *iff, int UNUSED(dict))
 {
-    free(iff->features);
+    LY_ARRAY_FREE(iff->features);
     free(iff->expr);
 }
 
@@ -469,7 +460,7 @@
 {
     FREE_STRING(ctx, feat->name, dict);
     FREE_ARRAY(ctx, feat->iffeatures, lysc_iffeature_free);
-    free(feat->depfeatures);
+    LY_ARRAY_FREE(feat->depfeatures);
 }
 
 static void
@@ -600,7 +591,7 @@
 
     /* we have the correct module, get the feature */
     LY_ARRAY_FOR(mod->features, i) {
-        f = LY_ARRAY_INDEX(mod->features, i);
+        f = &mod->features[i];
         if (!strncmp(f->name, name, len) && f->name[len] == '\0') {
             return f;
         }
@@ -621,7 +612,7 @@
     switch (op) {
     case LYS_IFF_F:
         /* resolve feature */
-        return lysc_feature_value(*LY_ARRAY_INDEX(iff->features, (*index_f)++, struct lysc_feature*));
+        return lysc_feature_value(iff->features[(*index_f)++]);
     case LYS_IFF_NOT:
         /* invert result */
         return lysc_iffeature_value_(iff, index_e, index_f) ? 0 : 1;
@@ -690,7 +681,7 @@
     changed = ly_set_new();
 
     for (u = 0; u < LY_ARRAY_SIZE(mod->features); ++u) {
-        f = LY_ARRAY_INDEX(mod->features, u);
+        f = &mod->features[u];
         if (all || !strcmp(f->name, name)) {
             if ((value && (f->flags & LYS_FENABLED)) || (!value && !(f->flags & LYS_FENABLED))) {
                 if (all) {
@@ -802,7 +793,7 @@
 
     /* search for the specified feature */
     for (u = 0; u < LY_ARRAY_SIZE(mod->features); ++u) {
-        f = LY_ARRAY_INDEX(mod->features, u);
+        f = &mod->features[u];
         if (!strcmp(f->name, feature)) {
             if (f->flags & LYS_FENABLED) {
                 return 1;
@@ -897,12 +888,11 @@
     }
 
     /* allocate the memory */
+    LY_ARRAY_CREATE_RET(ctx->mod->ctx, iff->features, f_size, LY_EMEM);
     iff->expr = calloc((j = (expr_size / 4) + ((expr_size % 4) ? 1 : 0)), sizeof *iff->expr);
-    iff->features = malloc(sizeof(uint32_t) + (f_size * sizeof *iff->features));
     stack.stack = malloc(expr_size * sizeof *stack.stack);
-    LY_CHECK_ERR_GOTO(!stack.stack || !iff->expr || !iff->features, LOGMEM(ctx->mod->ctx), error);
+    LY_CHECK_ERR_GOTO(!stack.stack || !iff->expr, LOGMEM(ctx->mod->ctx), error);
 
-    *((uint32_t*)iff->features) = f_size;
     stack.size = expr_size;
     f_size--; expr_size--; /* used as indexes from now */
 
@@ -964,25 +954,11 @@
                                      "Invalid value \"%s\" of if-feature - unable to find feature \"%.*s\".", value, j - i, &c[i]);
                               rc = LY_EINVAL,
                               error)
-            *(LY_ARRAY_INDEX(iff->features, f_size, struct lysc_feature*)) = f;
+            iff->features[f_size] = f;
+            LY_ARRAY_INCREMENT(iff->features);
             if (parent) {
                 /* and add itself into the dependants list */
-                //LYSP_ARRAY_NEW_RET(ctx->mod->ctx, f->depfeatures, df, LY_EMEM);
-                if (!(f->depfeatures)) {
-                    f->depfeatures = malloc(sizeof(uint32_t) + sizeof *(f->depfeatures));
-                    *((uint32_t*)(f->depfeatures)) = 1;
-                } else {
-                    ++(*((uint32_t*)(f->depfeatures)));
-                    f->depfeatures = ly_realloc(f->depfeatures,
-                                                sizeof(uint32_t) + (*((uint32_t*)(f->depfeatures)) * sizeof *(f->depfeatures)));
-                    if (!(f->depfeatures)) {
-                        ly_log(ctx->mod->ctx, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
-                        return LY_EMEM;
-                    };
-                }
-                (df) = (void*)((uint32_t*)((f->depfeatures) + *((uint32_t*)(f->depfeatures)) - 1) + 1);
-                memset(df, 0, sizeof *(df));
-
+                LY_ARRAY_NEW_RET(ctx->mod->ctx, f->depfeatures, df, LY_EMEM);
                 *df = parent;
 
                 /* TODO check for circular dependency */
@@ -1028,13 +1004,12 @@
 
     if (feature_p->iffeatures) {
         /* allocate everything now */
-        feature->iffeatures = calloc(1, sizeof(uint32_t) + (*((uint32_t*)(feature_p->iffeatures)) * sizeof *feature->iffeatures));
-        *((uint32_t*)(feature->iffeatures)) = 0;
+        LY_ARRAY_CREATE_RET(ctx->mod->ctx, feature->iffeatures, LY_ARRAY_SIZE(feature_p->iffeatures), LY_EMEM);
 
         for (u = 0; u < LY_ARRAY_SIZE(feature_p->iffeatures); ++u) {
-            ret = lys_compile_iffeature(ctx, *LY_ARRAY_INDEX(feature_p->iffeatures, u, const char *), options, LY_ARRAY_INDEX(feature->iffeatures, u), feature);
+            ret = lys_compile_iffeature(ctx, feature_p->iffeatures[u], options, &feature->iffeatures[u], feature);
             LY_CHECK_RET(ret);
-            ++(*((uint32_t*)(feature->iffeatures)));
+            LY_ARRAY_INCREMENT(feature->iffeatures);
         }
     }
 
@@ -1075,13 +1050,12 @@
 
     if (sp->features) {
         /* allocate everything now */
-        mod_c->features = calloc(1, sizeof(uint32_t) + (*((uint32_t*)(sp->features)) * sizeof *mod_c->features));
-        *((uint32_t*)(mod_c->features)) = 0;
+        LY_ARRAY_CREATE_RET(ctx.mod->ctx, mod_c->features, LY_ARRAY_SIZE(sp->features), LY_EMEM);
 
         for (u = 0; u < LY_ARRAY_SIZE(sp->features); ++u) {
-            ret = lys_compile_feature(&ctx, LY_ARRAY_INDEX(sp->features, u), options, LY_ARRAY_INDEX(mod_c->features, u));
+            ret = lys_compile_feature(&ctx, &sp->features[u], options, &mod_c->features[u]);
             LY_CHECK_GOTO(ret != LY_SUCCESS, error);
-            ++(*((uint32_t*)(mod_c->features)));
+            LY_ARRAY_INCREMENT(mod_c->features);
         }
     }
 
@@ -1134,9 +1108,9 @@
 
     if (revision) {
         /* check revision of the parsed model */
-        if (!mod->parsed->revs || strcmp(revision, LY_ARRAY_INDEX(mod->parsed->revs, 0, struct lysp_revision)->rev)) {
+        if (!mod->parsed->revs || strcmp(revision, mod->parsed->revs[0].rev)) {
             LOGERR(ctx, LY_EINVAL, "Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
-                   mod->parsed->name, LY_ARRAY_INDEX(mod->parsed->revs, 0, struct lysp_revision)->rev, revision);
+                   mod->parsed->name, mod->parsed->revs[0].rev, revision);
             lysp_module_free(mod->parsed);
             free(mod);
             return NULL;
@@ -1264,9 +1238,9 @@
     }
     if (rev) {
         len = dot - ++rev;
-        if (!mod->parsed->revs || len != 10 || strncmp(LY_ARRAY_INDEX(mod->parsed->revs, 0, struct lysp_revision)->rev, rev, len)) {
+        if (!mod->parsed->revs || len != 10 || strncmp(mod->parsed->revs[0].rev, rev, len)) {
             LOGWRN(ctx, "File name \"%s\" does not match module revision \"%s\".", filename,
-                   mod->parsed->revs ? LY_ARRAY_INDEX(mod->parsed->revs, 0, struct lysp_revision)->rev : "none");
+                   mod->parsed->revs ? mod->parsed->revs[0].rev : "none");
         }
     }
 
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 2f23541..12394eb 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -32,16 +32,6 @@
 #define LY_ARRAY_SELECT(_1, _2, NAME, ...) NAME
 
 /**
- * @brief Get void pointer to the item on the INDEX in the ARRAY
- */
-#define LY_ARRAY_INDEX1(ARRAY, INDEX) ((void*)((uint32_t*)((ARRAY) + INDEX) + 1))
-
-/**
- * @brief Get the TYPE pointer to the item on the INDEX in the ARRAY
- */
-#define LY_ARRAY_INDEX2(ARRAY, INDEX, TYPE) ((TYPE*)((uint32_t*)((ARRAY) + INDEX) + 1))
-
-/**
  * @brief Helper macro to go through sized-arrays with a pointer iterator.
  *
  * Use with opening curly bracket (`{`).
@@ -51,8 +41,8 @@
  * @param[out] ITER Iterating pointer to the item being processed in each loop
  */
 #define LY_ARRAY_FOR_ITER(ARRAY, TYPE, ITER) \
-    for (ITER = LY_ARRAY_INDEX1(ARRAY, 0); \
-         (ARRAY) && ((void*)ITER - (void*)ARRAY - sizeof(uint32_t))/(sizeof(TYPE)) < (*(uint32_t*)(ARRAY)); \
+    for (ITER = ARRAY; \
+         (ARRAY) && ((void*)ITER - (void*)ARRAY)/(sizeof(TYPE)) < (*((uint32_t*)(ARRAY) - 1)); \
          ITER = (void*)((TYPE*)ITER + 1))
 
 /**
@@ -67,7 +57,7 @@
  */
 #define LY_ARRAY_FOR_INDEX(ARRAY, INDEX) \
     for (INDEX = 0; \
-         ARRAY && INDEX < (*((uint32_t*)(ARRAY))); \
+         ARRAY && INDEX < (*((uint32_t*)(ARRAY) - 1)); \
          ++INDEX)
 
 /**
@@ -78,18 +68,11 @@
  */
 
 /**
- * @brief Get (optionally TYPEd) pointer to the item on the INDEX in the ARRAY
- *
- *     LY_ARRAY_INDEX(ARRAY, INDEX [, TYPE])
- */
-#define LY_ARRAY_INDEX(ARRAY, ...) LY_ARRAY_SELECT(__VA_ARGS__, LY_ARRAY_INDEX2, LY_ARRAY_INDEX1)(ARRAY, __VA_ARGS__)
-
-/**
  * @brief Get a number of records in the ARRAY.
  *
  * Does not check if array exists!
  */
-#define LY_ARRAY_SIZE(ARRAY) (*((uint32_t*)(ARRAY)))
+#define LY_ARRAY_SIZE(ARRAY) (*((uint32_t*)(ARRAY) - 1))
 
 /**
  * @brief Sized-array iterator (for-loop).
@@ -106,8 +89,7 @@
  *     LY_ARRAY_FOR(ARRAY, INDEX)
  *
  * The ARRAY is again a sized-array to go through, the INDEX is a variable (unsigned integer) for storing iterating ARRAY's index
- * to access the items of ARRAY in the loops. The INDEX is supposed to be used via LY_ARRAY_INDEX macro which can provide the item
- * in the loop body. This functionality is provided by LY_ARRAY_FOR_INDEX macro.
+ * to access the items of ARRAY in the loops. This functionality is provided by LY_ARRAY_FOR_INDEX macro.
  */
 #define LY_ARRAY_FOR(ARRAY, ...) LY_ARRAY_SELECT(__VA_ARGS__, LY_ARRAY_FOR_ITER, LY_ARRAY_FOR_INDEX)(ARRAY, __VA_ARGS__)
 
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index c08068a..0d0620c 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -92,17 +92,16 @@
     struct lysp_revision rev;
 
     for (i = 1, r = 0; revs && i < LY_ARRAY_SIZE(revs); i++) {
-        if (strcmp(LY_ARRAY_INDEX(revs, i, struct lysp_revision)->rev,
-                   LY_ARRAY_INDEX(revs, r, struct lysp_revision)->rev) > 0) {
+        if (strcmp(revs[i].rev, revs[r].rev) > 0) {
             r = i;
         }
     }
 
     if (r) {
         /* the newest revision is not on position 0, switch them */
-        memcpy(&rev, LY_ARRAY_INDEX(revs, 0), sizeof rev);
-        memcpy(LY_ARRAY_INDEX(revs, 0), LY_ARRAY_INDEX(revs, r), sizeof rev);
-        memcpy(LY_ARRAY_INDEX(revs, r), &rev, sizeof rev);
+        memcpy(&rev, &revs[0], sizeof rev);
+        memcpy(&revs[0], &revs[r], sizeof rev);
+        memcpy(&revs[r], &rev, sizeof rev);
     }
 }
 
diff --git a/tests/src/test_parser_yang.c b/tests/src/test_parser_yang.c
index e6fec3c..db73f63 100644
--- a/tests/src/test_parser_yang.c
+++ b/tests/src/test_parser_yang.c
@@ -725,7 +725,7 @@
     TEST_NODE(LYS_ANYXML, "anyxml test;}", "test");
     /* augment */
     TEST_GENERIC("augment /somepath;}", mod->augments,
-                 assert_string_equal("/somepath", LY_ARRAY_INDEX(mod->augments, 0, struct lysp_augment)->nodeid));
+                 assert_string_equal("/somepath", mod->augments[0].nodeid));
     /* choice */
     TEST_NODE(LYS_CHOICE, "choice test;}", "test");
     /* contact 0..1 */
@@ -738,22 +738,22 @@
                  assert_string_equal("some description", mod->dsc));
     /* deviation */
     TEST_GENERIC("deviation /somepath {deviate not-supported;}}", mod->deviations,
-                 assert_string_equal("/somepath", LY_ARRAY_INDEX(mod->deviations, 0, struct lysp_deviation)->nodeid));
+                 assert_string_equal("/somepath", mod->deviations[0].nodeid));
     /* extension */
     TEST_GENERIC("extension test;}", mod->extensions,
-                 assert_string_equal("test", LY_ARRAY_INDEX(mod->extensions, 0, struct lysp_ext)->name));
+                 assert_string_equal("test", mod->extensions[0].name));
     /* feature */
     TEST_GENERIC("feature test;}", mod->features,
-                 assert_string_equal("test", LY_ARRAY_INDEX(mod->features, 0, struct lysp_feature)->name));
+                 assert_string_equal("test", mod->features[0].name));
     /* grouping */
     TEST_GENERIC("grouping grp;}", mod->groupings,
-                 assert_string_equal("grp", LY_ARRAY_INDEX(mod->groupings, 0, struct lysp_grp)->name));
+                 assert_string_equal("grp", mod->groupings[0].name));
     /* identity */
     TEST_GENERIC("identity test;}", mod->identities,
-                 assert_string_equal("test", LY_ARRAY_INDEX(mod->identities, 0, struct lysp_ident)->name));
+                 assert_string_equal("test", mod->identities[0].name));
     /* import */
     TEST_GENERIC("import test {prefix z;}}", mod->imports,
-                 assert_string_equal("test", LY_ARRAY_INDEX(mod->imports, 0, struct lysp_import)->name));
+                 assert_string_equal("test", mod->imports[0].name));
 
     /* import - prefix collision */
     str = SCHEMA_BEGINNING "import test {prefix x;}}";
@@ -767,7 +767,7 @@
 
     /* include */
     TEST_GENERIC("include test;}", mod->includes,
-                 assert_string_equal("test", LY_ARRAY_INDEX(mod->includes, 0, struct lysp_include)->name));
+                 assert_string_equal("test", mod->includes[0].name));
     /* leaf */
     TEST_NODE(LYS_LEAF, "leaf test {type string;}}", "test");
     /* leaf-list */
@@ -776,7 +776,7 @@
     TEST_NODE(LYS_LIST, "list test {key a;leaf a {type string;}}}", "test");
     /* notification */
     TEST_GENERIC("notification test;}", mod->notifs,
-                 assert_string_equal("test", LY_ARRAY_INDEX(mod->notifs, 0, struct lysp_notif)->name));
+                 assert_string_equal("test", mod->notifs[0].name));
     /* organization 0..1 */
     TEST_GENERIC("organization \"CESNET a.l.e.\";}", mod->org,
                  assert_string_equal("CESNET a.l.e.", mod->org));
@@ -785,13 +785,13 @@
                  assert_string_equal("RFC7950", mod->ref));
     /* revision */
     TEST_GENERIC("revision 2018-10-12;}", mod->revs,
-                 assert_string_equal("2018-10-12", LY_ARRAY_INDEX(mod->revs, 0, struct lysp_revision)->rev));
+                 assert_string_equal("2018-10-12", mod->revs[0].rev));
     /* rpc */
     TEST_GENERIC("rpc test;}", mod->rpcs,
-                 assert_string_equal("test", LY_ARRAY_INDEX(mod->rpcs, 0, struct lysp_action)->name));
+                 assert_string_equal("test", mod->rpcs[0].name));
     /* typedef */
     TEST_GENERIC("typedef test{type string;}}", mod->typedefs,
-                 assert_string_equal("test", LY_ARRAY_INDEX(mod->typedefs, 0, struct lysp_tpdf)->name));
+                 assert_string_equal("test", mod->typedefs[0].name));
     /* uses */
     TEST_NODE(LYS_USES, "uses test;}", "test");
     /* yang-version */
@@ -814,8 +814,8 @@
 
     /* extensions */
     TEST_GENERIC("prefix:test;}", mod->exts,
-                 assert_string_equal("prefix:test", LY_ARRAY_INDEX(mod->exts, 0, struct lysp_ext_instance)->name);
-                 assert_int_equal(LYEXT_SUBSTMT_SELF, LY_ARRAY_INDEX(mod->exts, 0, struct lysp_ext_instance)->insubstmt));
+                 assert_string_equal("prefix:test", mod->exts[0].name);
+                 assert_int_equal(LYEXT_SUBSTMT_SELF, mod->exts[0].insubstmt));
     mod = mod_renew(&ctx, mod, 0);
 
     /* invalid substatement */
diff --git a/tests/src/test_tree_schema_compile.c b/tests/src/test_tree_schema_compile.c
index 8e72276..79c7c42 100644
--- a/tests/src/test_tree_schema_compile.c
+++ b/tests/src/test_tree_schema_compile.c
@@ -94,14 +94,14 @@
     /* features */
     assert_non_null(mod.compiled->features);
     assert_int_equal(2, LY_ARRAY_SIZE(mod.compiled->features));
-    f = LY_ARRAY_INDEX(mod.compiled->features, 1);
+    f = &mod.compiled->features[1];
     assert_non_null(f->iffeatures);
     assert_int_equal(1, LY_ARRAY_SIZE(f->iffeatures));
-    iff = LY_ARRAY_INDEX(f->iffeatures, 0);
+    iff = &f->iffeatures[0];
     assert_non_null(iff->expr);
     assert_non_null(iff->features);
     assert_int_equal(1, LY_ARRAY_SIZE(iff->features));
-    assert_ptr_equal(LY_ARRAY_INDEX(mod.compiled->features, 0), *LY_ARRAY_INDEX(iff->features, 0, struct lysc_feature*));
+    assert_ptr_equal(&mod.compiled->features[0], iff->features[0]);
 
     lysc_module_free(mod.compiled, NULL);
 
@@ -153,17 +153,17 @@
     }
     /* enable f1 */
     assert_int_equal(LY_SUCCESS, lys_feature_enable(&mod, "f1"));
-    f1 = LY_ARRAY_INDEX(mod.compiled->features, 0);
+    f1 = &mod.compiled->features[0];
     assert_int_equal(1, lysc_feature_value(f1));
 
     /* enable f4 */
-    f = LY_ARRAY_INDEX(mod.compiled->features, 3);
+    f = &mod.compiled->features[3];
     assert_int_equal(0, lysc_feature_value(f));
     assert_int_equal(LY_SUCCESS, lys_feature_enable(&mod, "f4"));
     assert_int_equal(1, lysc_feature_value(f));
 
     /* enable f5 - no possible since f2 is disabled */
-    f = LY_ARRAY_INDEX(mod.compiled->features, 4);
+    f = &mod.compiled->features[4];
     assert_int_equal(0, lysc_feature_value(f));
     assert_int_equal(LY_EDENIED, lys_feature_enable(&mod, "f5"));
     logbuf_assert("Feature \"f5\" cannot be enabled since it is disabled by its if-feature condition(s).");
@@ -175,7 +175,7 @@
     assert_int_equal(1, lysc_feature_value(f));
 
     /* f1 is enabled, so f6 cannot be enabled */
-    f = LY_ARRAY_INDEX(mod.compiled->features, 5);
+    f = &mod.compiled->features[5];
     assert_int_equal(0, lysc_feature_value(f));
     assert_int_equal(LY_EDENIED, lys_feature_enable(&mod, "f6"));
     logbuf_assert("Feature \"f6\" cannot be enabled since it is disabled by its if-feature condition(s).");
@@ -183,19 +183,17 @@
 
     /* so disable f1 - f5 will became also disabled */
     assert_int_equal(1, lysc_feature_value(f1));
-    f = LY_ARRAY_INDEX(mod.compiled->features, 4);
     assert_int_equal(LY_SUCCESS, lys_feature_disable(&mod, "f1"));
     assert_int_equal(0, lysc_feature_value(f1));
-    assert_int_equal(0, lysc_feature_value(f));
+    assert_int_equal(0, lysc_feature_value(&mod.compiled->features[4]));
     /* while f4 is stille enabled */
-    assert_int_equal(1, lysc_feature_value(LY_ARRAY_INDEX(mod.compiled->features, 3)));
+    assert_int_equal(1, lysc_feature_value(&mod.compiled->features[3]));
     /* and finally f6 can be enabled */
-    f = LY_ARRAY_INDEX(mod.compiled->features, 5);
     assert_int_equal(LY_SUCCESS, lys_feature_enable(&mod, "f6"));
-    assert_int_equal(1, lysc_feature_value(f));
+    assert_int_equal(1, lysc_feature_value(&mod.compiled->features[5]));
 
     /* complex evaluation of f7: f1 and f3 are disabled, while f2 is enabled */
-    assert_int_equal(1, lysc_iffeature_value(LY_ARRAY_INDEX(LY_ARRAY_INDEX(mod.compiled->features, 6, struct lysc_feature)->iffeatures, 0)));
+    assert_int_equal(1, lysc_iffeature_value(&mod.compiled->features[6].iffeatures[0]));
 
     lysc_module_free(mod.compiled, NULL);
     lysp_module_free(mod.parsed);
diff --git a/tests/src/test_tree_schema_helpers.c b/tests/src/test_tree_schema_helpers.c
index 67f4138..3dc7d7c 100644
--- a/tests/src/test_tree_schema_helpers.c
+++ b/tests/src/test_tree_schema_helpers.c
@@ -90,20 +90,20 @@
     logbuf_assert("");
 
     /* revisions are stored in wrong order - the newest is the last */
-    LYSP_ARRAY_NEW_RET(NULL, revs, rev,);
+    LY_ARRAY_NEW_RET(NULL, revs, rev,);
     strcpy(rev->rev, "2018-01-01");
-    LYSP_ARRAY_NEW_RET(NULL, revs, rev,);
+    LY_ARRAY_NEW_RET(NULL, revs, rev,);
     strcpy(rev->rev, "2018-12-31");
 
     assert_int_equal(2, LY_ARRAY_SIZE(revs));
-    assert_string_equal("2018-01-01", LY_ARRAY_INDEX(revs, 0));
-    assert_string_equal("2018-12-31", LY_ARRAY_INDEX(revs, 1));
+    assert_string_equal("2018-01-01", &revs[0]);
+    assert_string_equal("2018-12-31", &revs[1]);
     /* the order should be fixed, so the newest revision will be the first in the array */
     lysp_sort_revisions(revs);
-    assert_string_equal("2018-12-31", LY_ARRAY_INDEX(revs, 0));
-    assert_string_equal("2018-01-01", LY_ARRAY_INDEX(revs, 1));
+    assert_string_equal("2018-12-31", &revs[0]);
+    assert_string_equal("2018-01-01", &revs[1]);
 
-    free(revs);
+    LY_ARRAY_FREE(revs);
 }
 
 int main(void)