{"id":13670544,"url":"https://github.com/eteran/c-vector","last_synced_at":"2025-05-15T02:08:31.079Z","repository":{"id":2521009,"uuid":"41334798","full_name":"eteran/c-vector","owner":"eteran","description":"A dynamic array implementation in C similar to the one found in standard C++","archived":false,"fork":false,"pushed_at":"2025-04-09T00:14:35.000Z","size":132,"stargazers_count":794,"open_issues_count":2,"forks_count":115,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-05-04T22:52:10.098Z","etag":null,"topics":["array","c","vector"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eteran.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-08-25T01:00:33.000Z","updated_at":"2025-04-29T15:45:49.000Z","dependencies_parsed_at":"2024-05-03T02:45:03.943Z","dependency_job_id":"a994af9c-6f13-4b95-bb78-159781827174","html_url":"https://github.com/eteran/c-vector","commit_stats":{"total_commits":86,"total_committers":16,"mean_commits":5.375,"dds":0.4534883720930233,"last_synced_commit":"532391e543eb712843eb3cd462d6356623645616"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eteran%2Fc-vector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eteran%2Fc-vector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eteran%2Fc-vector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eteran%2Fc-vector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eteran","download_url":"https://codeload.github.com/eteran/c-vector/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254259384,"owners_count":22040820,"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","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":["array","c","vector"],"created_at":"2024-08-02T09:00:44.843Z","updated_at":"2025-05-15T02:08:31.033Z","avatar_url":"https://github.com/eteran.png","language":"C","readme":"[![c-cpp-badge](https://github.com/eteran/c-vector/actions/workflows/cmake.yml/badge.svg)](https://github.com/eteran/c-vector/actions/workflows/cmake.yml)\n[![CodeQL](https://github.com/eteran/c-vector/actions/workflows/codeql-analysis.yml/badge.svg?branch=master)](https://github.com/eteran/c-vector/actions/workflows/codeql-analysis.yml)\n\nThis is an implementation of a `std::vector` like growable array, but in plain\nC89 code. The result is a type safe, easy to use, dynamic array that has a\nfamiliar set of operations.\n\nIt works by using the same trick as many allocators, which is to slightly\nallocate more data than requested, and using that extra padding in the front\nas storage for meta-data. Thus any non-null vector looks like this in memory:\n\n\t+------+----------+-----------------+---------+\n\t| size | capacity | elem_destructor | data... |\n\t+------+----------+-----------------+---------+\n\t                                    ^\n\t                                    | user's pointer\n\nWhere the user is given a pointer to first element of `data`. This way the\ncode has trivial access to the necessary meta-data, but the user need not be\nconcerned with these details. The total overhead is\n`2 * sizeof(size_t) + sizeof(void (*)(void *))` per vector.\n\nTo allow the code to be maximally generic, it is implemented as all macros, and\nis thus header only. Usage is simple:\n```c\n/* if this is defined, then the vector will increase in capacity by one\n * each time it runs out of space. if it is not defined, then the vector will\n * be liberal, and will double in capacity each time it runs out of space.\n * having this defined will minimize how much unused space is allocated.\n */\n#define CVECTOR_LINEAR_GROWTH\n\n#include \"cvector.h\"\n#include \u003cstdio.h\u003e\n\nint main(int argc, char *argv[]) {\n\n\t/* this is the variable that will store the array, you can have\n\t * a vector of any type! For example, you may write float *v = NULL,\n\t * and you'd have a vector of floats :-). NULL will have a size\n\t * and capacity of 0. Additionally, vector_begin and vector_end will\n\t * return NULL on a NULL vector. Alternatively, for clarity of writing\n\t * you can use the cvector_vector_type macro to define a vector of a\n\t * given type.\n\t */\n\tcvector_vector_type(int) v = NULL;\n\n\t(void)argc;\n\t(void)argv;\n\n\t/* add some elements to the back */\n\tcvector_push_back(v, 10);\n\tcvector_push_back(v, 20);\n\tcvector_push_back(v, 30);\n\tcvector_push_back(v, 40);\n\n\t/* remove an element by specifying an array subscript */\n\tcvector_erase(v, 2);\n\n\t/* remove an element from the back */\n\tcvector_pop_back(v);\n\n\t/* print out some stats about the vector */\n\tprintf(\"pointer : %p\\n\", (void *)v);\n\tprintf(\"capacity: %lu\\n\", cvector_capacity(v));\n\tprintf(\"size    : %lu\\n\", cvector_size(v));\n\n\t/* iterator over the vector using \"iterator\" style */\n\tif (v) {\n\t\tint *it;\n\t\tint i = 0;\n\t\tfor (it = cvector_begin(v); it != cvector_end(v); ++it) {\n\t\t\tprintf(\"v[%d] = %d\\n\", i, *it);\n\t\t\t++i;\n\t\t}\n\t}\n\n\t/* iterator over the vector standard indexing too! */\n\tif (v) {\n\t\tsize_t i;\n\t\tfor (i = 0; i \u003c cvector_size(v); ++i) {\n\t\t\tprintf(\"v[%lu] = %d\\n\", i, v[i]);\n\t\t}\n\t}\n\n\t/* well, we don't have destructors, so let's clean things up */\n\tcvector_free(v);\n\n\treturn 0;\n}\n\n```\n\n### API\n\n| `std::vector` | `cvector` |\n| ------------- | --------- |\n| [`std::vector\u003cint\u003e v`](https://en.cppreference.com/w/cpp/container/vector/vector) | `cvector(int) v` |\n| [Destructor](https://en.cppreference.com/w/cpp/container/vector/%7Evector) | `cvector_free(v)` |\n| [`v.at(3)`](https://en.cppreference.com/w/cpp/container/vector/at) | `cvector_at(v, 3)` |\n| [`v[3]`](https://en.cppreference.com/w/cpp/container/vector/operator_at) | `v[3]` |\n| [`v.front()`](https://en.cppreference.com/w/cpp/container/vector/front) | `cvector_front(v)` |\n| [`v.back()`](https://en.cppreference.com/w/cpp/container/vector/back) | `cvector_back(v)` |\n| [`v.begin()`](https://en.cppreference.com/w/cpp/container/vector/begin) | `cvector_begin(v)` |\n| [`v.end()`](https://en.cppreference.com/w/cpp/container/vector/begin) | `cvector_end(v)` |\n| [`v.empty()`](https://en.cppreference.com/w/cpp/container/vector/empty) | `cvector_empty(v)` |\n| [`v.size()`](https://en.cppreference.com/w/cpp/container/vector/size) | `cvector_size(v)` |\n| [`v.capacity()`](https://en.cppreference.com/w/cpp/container/vector/capacity) | `cvector_capacity(v)` |\n| [`v.shrink_to_fit()`](https://en.cppreference.com/w/cpp/container/vector/shrink_to_fit) | `cvector_shrink_to_fit(v)` |\n| [`v.clear()`](https://en.cppreference.com/w/cpp/container/vector/clear) | `cvector_clear(v)` |\n| [`v.insert(pos, value)`](https://en.cppreference.com/w/cpp/container/vector/insert) | `cvector_insert(v, pos, value)` |\n| [`v.erase(v.begin() + 2)`](https://en.cppreference.com/w/cpp/container/vector/erase) | `cvector_erase(v, 2)` |\n| [`v.push_back(value)`](https://en.cppreference.com/w/cpp/container/vector/push_back) | `cvector_push_back(v, value)` |\n| [`v.pop_back()`](https://en.cppreference.com/w/cpp/container/vector/pop_back) | `cvector_pop_back(v)` |\n| [`v.reserve(new_cap)`](https://en.cppreference.com/w/cpp/container/vector/reserve) | `cvector_reserve(v, new_cap)` |\n| [`v.resize(count)`](https://en.cppreference.com/w/cpp/container/vector/resize) | `cvector_resize(v, count)` |\n| [`v.swap(other)`](https://en.cppreference.com/w/cpp/container/vector/swap) | `cvector_swap(v, other)` |\n| [`std::vector\u003cint\u003e other = v;`](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) | `cvector(int) other; cvector_copy(v, other);` |\n\n\n### Notes\n* If you like this library, [german-one](https://github.com/german-one) has created a string library using this approach: https://github.com/german-one/c-string\n  \n","funding_links":[],"categories":["C"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feteran%2Fc-vector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feteran%2Fc-vector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feteran%2Fc-vector/lists"}