Created
February 27, 2024 07:36
-
-
Save rexim/b5b0c38f53157037923e7cdd77ce685d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#define da_append(xs, x) \ | |
do { \ | |
if ((xs)->count >= (xs)->capacity) { \ | |
if ((xs)->capacity == 0) (xs)->capacity = 256; \ | |
else (xs)->capacity *= 2; \ | |
(xs)->items = realloc((xs)->items, (xs)->capacity*sizeof(*(xs)->items)); \ | |
} \ | |
\ | |
(xs)->items[(xs)->count++] = (x); \ | |
} while (0) | |
typedef struct { | |
int *items; | |
size_t count; | |
size_t capacity; | |
} Numbers; | |
int main(void) | |
{ | |
Numbers xs = {0}; | |
for (int x = 0; x < 10; ++x) da_append(&xs, x); | |
for (size_t i = 0; i < xs.count; ++i) printf("%d\n", xs.items[i]); | |
return 0; | |
} |
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct {
int *items;
int count;
int capacity;
} Numbers;
void resize(Numbers *xs, int new_capacity) {
if (new_capacity < xs->count) {
xs->count = new_capacity;
}
xs->items = realloc(xs->items, new_capacity * sizeof(*xs->items));
xs->capacity = new_capacity;
}
void append(Numbers *xs, int x) {
if (xs->count >= xs->capacity) {
if (xs->capacity == 0) {
xs->capacity = 64;
} else {
xs->capacity *= 2;
}
resize(xs, xs->capacity);
}
xs->items[xs->count++] = x;
}
int get(Numbers *xs, int index) {
return xs->items[index];
}
int size(Numbers *xs) {
return xs->count;
}
int main(void) {
Numbers xs;
for (int i = 0; i < 10; ++i){
append(&xs, i);
}
for (int i = 0; i < size(&xs); ++i){
printf("%d\n", get(&xs, i));
}
return 0;
}```
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> typedef struct { int *items; int count; int capacity; } Numbers; void resize(Numbers *xs, int new_capacity) { if (new_capacity < xs->count) { xs->count = new_capacity; } xs->items = realloc(xs->items, new_capacity * sizeof(*xs->items)); xs->capacity = new_capacity; } void append(Numbers *xs, int x) { if (xs->count >= xs->capacity) { if (xs->capacity == 0) { xs->capacity = 64; } else { xs->capacity *= 2; } resize(xs, xs->capacity); } xs->items[xs->count++] = x; } int get(Numbers *xs, int index) { return xs->items[index]; } int size(Numbers *xs) { return xs->count; } int main(void) { Numbers xs; for (int i = 0; i < 10; ++i){ append(&xs, i); } for (int i = 0; i < size(&xs); ++i){ printf("%d\n", get(&xs, i)); } return 0; }```
Nice!
However re-assigning a pointer directly from realloc is potentially a memory leak and many tools will yell at you.('xs->items' may be set to null if 'realloc' fails, which may result in a leak of the original buffer from clang-tidy)
I know this is a tangent but its just a good to know.
void resize(Numbers* xs, int new_capacity) {
if (new_capacity < xs->count) {
xs->count = new_capacity;
}
int* new_items = realloc(xs->items, new_capacity * sizeof(*xs->items));
if (new_items == NULL) {
perror("realloc");
free(xs->items);
exit(1); // handle re-allocation failure
}
xs->items = new_items;
xs->capacity = new_capacity;
}
The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc().
Might wanna fix that and also somehow convey that to the user.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
you can make your array with "generic type":
#define DA_ARRAY( name, dtype)
typedef struct {
dtype* items;
size_t count;
size_t capacity;
} name##Array##_t; \