{"id":23508751,"url":"https://github.com/lovasko/m_array","last_synced_at":"2025-09-15T06:27:28.434Z","repository":{"id":36906409,"uuid":"41213431","full_name":"lovasko/m_array","owner":"lovasko","description":"C89 Dynamic Array","archived":false,"fork":false,"pushed_at":"2017-05-02T00:47:27.000Z","size":25,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-13T15:57:01.659Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lovasko.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-22T15:30:09.000Z","updated_at":"2019-10-21T09:36:14.000Z","dependencies_parsed_at":"2022-09-07T14:31:35.410Z","dependency_job_id":null,"html_url":"https://github.com/lovasko/m_array","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lovasko/m_array","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovasko%2Fm_array","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovasko%2Fm_array/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovasko%2Fm_array/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovasko%2Fm_array/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lovasko","download_url":"https://codeload.github.com/lovasko/m_array/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovasko%2Fm_array/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275216563,"owners_count":25425489,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-15T02:00:09.272Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-25T11:31:58.396Z","updated_at":"2025-09-15T06:27:28.375Z","avatar_url":"https://github.com/lovasko.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# m_array\nGeneral-purpose dynamic array implementation in the C89 language that runs on\nall POSIX-compatible systems.\n\n## Introduction \n### Objects\nThe design of the `m_array` expects the content to be homogeneous objects of\narbitrary size - from one byte upwards. The size of the object in bytes is set\nduring the call to the initialisation function `m_array_init`. All consequent\nfunction working with the array operate on objects (blocks of bytes) of such\nsize.\n\n### Access\nFunctions `m_array_get` and `m_array_set` allow to access or modify arbitrary\nelement of the array. In the case of the `set` function, it is possible to\nmodify multiple consecutive elements in one call.\n\n#### Bounds checking\nBoth `get` and `set` operations are protected with boundary checks with object\nsize granularity. Therefore, it is not possible to add new array elements with\nthe `set` call.\n\n### Growth factor\nBy definition, the dynamic array expands to necessary size when new elements\nare being appended. In order to minimise the number of calls to the potentially\ntime-expensive `realloc` function, `m_array` pre-allocates memory. By default,\nit doubles the current memory size - `M_ARRAY_GROWTH_EXPONENTIAL`. This growth\nstrategy might not be optimal at times and therefore, a second strategy that\nallocates only half of the current memory more - `M_ARRAY_GROWTH_CONSERVATIVE`.\nBoth of these constants have type `double`, with values `2.0` and `1.5`\nrespectively. It is possible to supply an entirely different growth factor\n(strictly great than `1.0`). To set the growth factor at any time, use the\n`m_array_growth_factor` function.\n\n### Memory management\nEven though `m_array` takes care of all things memory, its behaviour might not\nbe optimal in all scenarios. Therefore, it is possible to either grow or shrink\nthe underlying memory with the `m_array_resize` function.\n\n### Finalisation\nAdding elements to a `m_array` causes its internal memory buffers to grow. Once\nfinished with adding elements, it is possible that the `m_array` would still\nhold unused internal memory due to the prefetch, expecting elements to be\nadded. In order to release this memory back to the system, use the\n`m_array_trim` function.\n\n### Algorithms\nEven though the `m_array` supports random access to arbitrary elements with\nbounds checking, it is possible to perform certain high-level operations on the\nwhole list.\n\n#### Map\nIn order to apply a certain function to all objects stored in the `m_array`,\nuse the function `m_array_map`. Such function can be provided with an extra\nargument, a `payload` that can be used to provide additional data.\n\n#### Sort\nBy providing a comparison function `cmp_fn` to the `m_array_sort`, the function\nis able to sort the elements. There is no option to choose the direction of the\nsort (ascending vs descending), as this can be precisely controlled by the\ninner workings of the comparator function.\n\n#### Search\nIn order to search for an element, us the `m_array_search` function. By\nproviding the `key` and the comparator `cmp_fn`, the library is able to locate\nsuch element. Depending on the value of the `is_sorted`, either the more\noptimal binary search algorithm is performed - resulting in `O(logn)`\nperformance - or the linear walk from left to right through every element of\nthe array - resulting in `O(n)` performance.\n\n## Time and space complexity\nAll operations have `O(1)` space complexity.\n\n| Operation               | Time                 |\n|-------------------------|----------------------|\n| `m_array_append`        | `O(r)`               |\n| `m_array_get`           | `O(1)`               |\n| `m_array_growth_factor` | `O(1)`               |\n| `m_array_init`          | `O(1)`               |\n| `m_array_insert`        | `O(n)`               |\n| `m_array_length`        | `O(1)`               |\n| `m_array_map`           | `O(n)`               |\n| `m_array_prepend`       | `O(n)`               |\n| `m_array_remove_all`    | `O(n)`               |\n| `m_array_remove`        | `O(n)`               |\n| `m_array_resize`        | `O(r)`               |\n| `m_array_search`        | `O(n)` or `O(log n)` |\n| `m_array_set`           | `O(1)`               |\n| `m_array_sort`          | `O(q)`               |\n| `m_array_trim`          | `O(1)` or `O(n)`     |\n\nwhere:\n * `n` denotes the length of the array.\n * `r` is the complexity of the systems `realloc` function, usually `O(n)`\n * `q` is the complexity of the systems `qsort` function, usually `O(nlogn)`\n\n## Return codes \n### M_ARRAY_OK\nThe operation was successful.\n\n### M_ARRAY_E_NULL\nEither one or more of the arguments are `NULL`.\n\n### M_ARRAY_E_OUT_OF_BOUNDS\nThe array subscription index is greater than the actual size of the array.\n\n### M_ARRAY_E_GROWTH\nBased on the growth factor and the current size of the array it is not possible\nto grow enough so that the operation can proceed. In order to fix this, set the\ngrowth factor to a greater number with the `m_array_growth_factor` function and\nretry the operation.\n\n### M_ARRAY_NOT_FOUND\nThe `m_array_search` function was not able to locate the specified element.\n\n## Examples\n * [Median of open files count](examples/openfiles.md)\n\n## Supported platforms\n * FreeBSD 10.0 with Clang 3.3\n * OS X 10.9 with Clang 3.5\n * Linux Gentoo 2.2 with Clang 3.6\n\nIf a platform does not appear to be in the previous list, it does not mean that\n`m_array` will not work in such environment. It only means that nobody tested\nit - you are encouraged to do so and report either success or failure.\n\n## Build \u0026 install\n```\n$ ninja\n$ sudo ./install.sh\n```\n\n## License\n2-clause BSD license. For more information please consult the\n[LICENSE](LICENSE.md) file. In the case that you need a different license, feel\nfree to contact me.\n\n## Author\nDaniel Lovasko (daniel.lovasko@gmail.com)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flovasko%2Fm_array","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flovasko%2Fm_array","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flovasko%2Fm_array/lists"}