fork download
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. struct foo
  5. {
  6. int bar;
  7. double baz;
  8. };
  9.  
  10. struct vector
  11. {
  12. char* beg;
  13. char* last;
  14. char* end;
  15. size_t eltsiz;
  16. };
  17.  
  18. #define VECTOR_MIN_CAPACITY 2
  19.  
  20. struct vector* vector_create(size_t eltsiz)
  21. {
  22. struct vector* ret = malloc(sizeof(struct vector));
  23.  
  24. ret->beg = ret->last = malloc(eltsiz * VECTOR_MIN_CAPACITY);
  25. ret->end = ret->beg + eltsiz * VECTOR_MIN_CAPACITY;
  26. ret->eltsiz = eltsiz;
  27.  
  28. return ret;
  29. }
  30.  
  31. void vector_free(struct vector* vec)
  32. {
  33. free(vec->beg);
  34. free(vec);
  35.  
  36. return;
  37. }
  38.  
  39. void* vector_push(struct vector* vec)
  40. {
  41. if(vec->last == vec->end) {
  42. size_t space_occupied = vec->last - vec->beg;
  43. vec->beg = realloc(vec->beg, 2*space_occupied);
  44. vec->last = vec->beg + space_occupied;
  45. vec->end = vec->beg + 2*space_occupied;
  46. }
  47.  
  48. char* ret = vec->last;
  49. vec->last += vec->eltsiz;
  50. return ret;
  51. }
  52.  
  53. // UB if overflow.
  54. void* vector_get(struct vector* vec, size_t index)
  55. {
  56. return vec->beg + index*vec->eltsiz;
  57. }
  58.  
  59. // UB if called on an empty vector.
  60. void vector_pop(struct vector* vec)
  61. {
  62. vec->last -= vec->eltsiz;
  63.  
  64. size_t space_occupied = vec->last - vec->beg;
  65. if(space_occupied <= (vec->end-vec->beg)/4 &&
  66. space_occupied >= vec->eltsiz*VECTOR_MIN_CAPACITY) {
  67. vec->beg = realloc(vec->beg, 2*space_occupied);
  68. vec->last = vec->beg + space_occupied;
  69. vec->end = vec->beg + 2*space_occupied;
  70. }
  71.  
  72. return;
  73. }
  74.  
  75. int main()
  76. {
  77. struct foo sf1 = {.bar = 5, .baz = 15.51}; // May be safely copied.
  78.  
  79. struct vector* vec1 = vector_create(sizeof(struct foo));
  80. // sf1 is copied, vector stores the struct itself
  81. // rather than a pointer to this struct.
  82. *(struct foo*)vector_push(vec1) = sf1;
  83. *(struct foo*)vector_push(vec1) = (struct foo){.bar = -3, .baz = 100.01};
  84. // Last element is uninitialized.
  85. vector_push(vec1);
  86.  
  87. printf("%d\n", ((struct foo*)vector_get(vec1, 1))->bar);
  88.  
  89. struct foo sf2 = {.bar = 2, .baz = -23.32}; // Mustn't be copied!
  90.  
  91. struct vector* vec2 = vector_create(sizeof(struct foo*));
  92. // I avoid copying sf2, vector stores pointers to the struct
  93. // rather than the struct itself
  94. *(struct foo**)vector_push(vec2) = &sf2;
  95. *(struct foo**)vector_push(vec2) = malloc(sizeof(struct foo));
  96. **(struct foo**)vector_get(vec2, 1) = (struct foo){.bar = -4, .baz = -3.2};
  97. // Last element is NULL.
  98. *(struct foo**)vector_push(vec2) = NULL;
  99.  
  100. printf("%d\n", (*(struct foo**)vector_get(vec2, 1))->bar);
  101.  
  102. return 0;
  103. }
Success #stdin #stdout 0s 9424KB
stdin
Standard input is empty
stdout
-3
-4