summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorXuefer <xuefer@gmail.com>2014-11-08 07:38:45 +0000
committerXuefer <xuefer@gmail.com>2014-11-08 07:38:45 +0000
commitf664f5a518600b71055ffe871c16440439a25f2f (patch)
tree14fa36604ce00d4cf04b185e20bd02c006278f54 /util
parentc130a0d58900e7a024135a328dedb112df109995 (diff)
downloadxcache-f664f5a518600b71055ffe871c16440439a25f2f.tar.gz
xcache-f664f5a518600b71055ffe871c16440439a25f2f.zip
merge stack/vector to 1 impl, avoid possible memory leak using malloc
git-svn-id: svn://svn.lighttpd.net/xcache/trunk@1551 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
Diffstat (limited to 'util')
-rw-r--r--util/xc_stack.c66
-rw-r--r--util/xc_stack.h22
-rw-r--r--util/xc_vector.h118
-rw-r--r--util/xc_vector_test.c38
4 files changed, 130 insertions, 114 deletions
diff --git a/util/xc_stack.c b/util/xc_stack.c
deleted file mode 100644
index 25be04c..0000000
--- a/util/xc_stack.c
+++ /dev/null
@@ -1,66 +0,0 @@
-#include <stdlib.h>
-#include "xc_trace.h"
-#include "xc_stack.h"
-
-typedef xc_stack_t* S;
-
-void xc_stack_init_ex(S stack, int initsize)
-{
- stack->cnt = 0;
- stack->size = initsize;
- stack->data = malloc(sizeof(void *) * stack->size);
-}
-
-void xc_stack_destroy(S stack)
-{
- free(stack->data);
-}
-
-void xc_stack_push(S stack, void *item)
-{
- if (stack->cnt == stack->size) {
- stack->size <<= 1;
- stack->data = realloc(stack->data, sizeof(void *) * stack->size);
- }
- stack->data[stack->cnt++] = item;
-}
-
-void* xc_stack_pop(S stack)
-{
- assert(stack != NULL);
- assert(stack->size > 0);
- return stack->data[--stack->cnt];
-}
-
-void* xc_stack_top(S stack)
-{
- assert(stack != NULL);
- assert(stack->cnt > 0);
- return stack->data[stack->cnt-1];
-}
-
-void* xc_stack_get(S stack, int n)
-{
- assert(stack != NULL);
- assert(stack->cnt > 0);
- return stack->data[n];
-}
-
-int xc_stack_count(S stack)
-{
- assert(stack != NULL);
- return stack->cnt;
-}
-
-void xc_stack_reverse(S stack)
-{
- int i, j;
- void *tmp;
-
- assert(stack != NULL);
- for (i = 0, j = stack->cnt - 1; i < j; i ++, j --) {
- tmp = stack->data[i];
- stack->data[i] = stack->data[j];
- stack->data[j] = tmp;
- }
-}
diff --git a/util/xc_stack.h b/util/xc_stack.h
deleted file mode 100644
index 8f82870..0000000
--- a/util/xc_stack.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef __XC_UTIL_STACK
-#define __XC_UTIL_STACK
-
-typedef struct {
- void **data;
- int cnt;
- int size;
-} xc_stack_t;
-
-#define S xc_stack_t*
-void xc_stack_init_ex(S stack, int initsize);
-#define xc_stack_init(stack) xc_stack_init_ex(stack, 8)
-void xc_stack_destroy(S stack);
-void xc_stack_push(S stack, void *item);
-void *xc_stack_pop(S stack);
-void *xc_stack_top(S stack);
-void *xc_stack_get(S stack, int n);
-int xc_stack_count(S stack);
-void xc_stack_reverse(S stack);
-#undef S
-
-#endif /* __XC_UTIL_STACK */
diff --git a/util/xc_vector.h b/util/xc_vector.h
index 120b5d3..86ad804 100644
--- a/util/xc_vector.h
+++ b/util/xc_vector.h
@@ -5,52 +5,118 @@
#pragma once
#endif /* _MSC_VER > 1000 */
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
typedef struct {
- zend_uint size;
- zend_uint cnt;
+ size_t size;
void *data;
+
+ size_t capacity;
+ size_t data_size;
+ int persistent;
} xc_vector_t;
-#define xc_vector_init(type, vector) do { \
- (vector)->cnt = 0; \
- (vector)->size = 0; \
+#define xc_vector_initializer(type, persistent_) { \
+ 0, \
+ NULL, \
+\
+ 0, \
+ sizeof(type), \
+ persistent_, \
+}
+
+#define xc_vector_init(type, vector, persistent_) do { \
+ (vector)->size = 0; \
(vector)->data = NULL; \
+\
+ (vector)->capacity = 0; \
+ (vector)->data_size = sizeof(type); \
+ (vector)->persistent = persistent_; \
} while (0)
-#define xc_vector_add(type, vector, value) do { \
- if ((vector)->cnt == (vector)->size) { \
- if ((vector)->size) { \
- (vector)->size <<= 1; \
- (vector)->data = erealloc((vector)->data, sizeof(type) * (vector)->size); \
- } \
- else { \
- (vector)->size = 8; \
- (vector)->data = emalloc(sizeof(type) * (vector)->size); \
- } \
- } \
- ((type *) (vector)->data)[(vector)->cnt++] = value; \
+static inline void xc_vector_destroy_impl(xc_vector_t *vector TSRMLS_DC)
+{
+ if (vector->data) {
+ pefree(vector->data, vector->persistent);
+ }
+ vector->capacity = 0;
+ vector->size = 0;
+}
+
+#define xc_vector_destroy(vector) xc_vector_destroy_impl(vector TSRMLS_CC)
+
+#define xc_vector_size(vector) ((vector)->size)
+#define xc_vector_element_ptr_(vector, index) ( \
+ (void *) ( \
+ ((char *) (vector)->data) + (index) * (vector)->data_size \
+ ) \
+)
+
+static inline xc_vector_t *xc_vector_check_type_(xc_vector_t *vector, size_t data_size)
+{
+ assert(vector->data_size = data_size);
+ return vector;
+}
+
+#define xc_vector_data(type, vector) ((type *) xc_vector_check_type_(vector, sizeof(type))->data)
+
+static inline void xc_vector_check_reserve_(xc_vector_t *vector TSRMLS_DC)
+{
+ if (vector->size == vector->capacity) {
+ if (vector->capacity) {
+ vector->capacity <<= 1;
+ vector->data = perealloc(vector->data, vector->data_size * vector->capacity, vector->persistent);
+ }
+ else {
+ vector->capacity = 8;
+ vector->data = pemalloc(vector->data_size * vector->capacity, vector->persistent);
+ }
+ }
+}
+
+#define xc_vector_push_back(vector, value_ptr) do { \
+ xc_vector_check_reserve_(vector TSRMLS_CC); \
+ memcpy(xc_vector_element_ptr_(vector, (vector)->size++), value_ptr, (vector)->data_size); \
} while (0)
static inline void *xc_vector_detach_impl(xc_vector_t *vector)
{
void *data = vector->data;
+
vector->data = NULL;
+ vector->capacity = 0;
vector->size = 0;
- vector->cnt = 0;
return data;
}
-#define xc_vector_detach(type, vector) ((type *) xc_vector_detach_impl(vector))
+#define xc_vector_detach(type, vector) ((type *) xc_vector_detach_impl(xc_vector_check_type_(vector, sizeof(type))))
-static inline void xc_vector_free_impl(xc_vector_t *vector TSRMLS_DC)
+static inline xc_vector_t *xc_vector_pop_back_check_(xc_vector_t *vector, size_t data_size)
{
- if (vector->data) {
- efree(vector->data);
- }
- vector->size = 0;
- vector->cnt = 0;
+ assert(vector);
+ assert(vector->data_size == data_size);
+ assert(vector->capacity > 0);
+ return vector;
}
-#define xc_vector_free(type, vector) xc_vector_free_impl(vector TSRMLS_CC)
+#define xc_vector_pop_back(type, vector) xc_vector_data(type, \
+ xc_vector_pop_back_check_(vector, sizeof(type)) \
+)[--(vector)->size]
+
+static inline void xc_vector_reverse(xc_vector_t *vector)
+{
+ char *left, *right;
+ void *tmp;
+
+ assert(vector);
+ tmp = alloca(vector->data_size);
+ for (left = vector->data, right = xc_vector_element_ptr_(vector, vector->size - 1); left < right; left += vector->data_size, right -= vector->data_size) {
+ memcpy(tmp, left, vector->data_size);
+ memcpy(left, right, vector->data_size);
+ memcpy(right, tmp, vector->data_size);
+ }
+}
#endif /* XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B */
diff --git a/util/xc_vector_test.c b/util/xc_vector_test.c
new file mode 100644
index 0000000..97582f2
--- /dev/null
+++ b/util/xc_vector_test.c
@@ -0,0 +1,38 @@
+
+#define TSRMLS_DC
+#define TSRMLS_CC
+#define pemalloc(size, p) malloc(size)
+#define perealloc(ptr, size, p) realloc(ptr, size)
+#define pefree(ptr, p) free(ptr)
+
+#include <stdio.h>
+#include "xc_vector.h"
+
+#undef CHECK
+#define CHECK(a, msg) do { \
+ if (!(a)) { \
+ fprintf(stderr, "%s\n", msg); return -1; \
+ } \
+} while (0)
+
+int main() /* {{{ */
+{
+ xc_vector_t vector = xc_vector_initializer(int, 0);
+ int t;
+
+ t = 1; xc_vector_push_back(&vector, &t);
+ t = 2; xc_vector_push_back(&vector, &t);
+ t = 3; xc_vector_push_back(&vector, &t);
+ xc_vector_reverse(&vector);
+ t = xc_vector_pop_back(int, &vector);
+ CHECK(t == 1, "not 1");
+ t = xc_vector_pop_back(int, &vector);
+ CHECK(t == 2, "not 2");
+ t = xc_vector_pop_back(int, &vector);
+ CHECK(t == 3, "not 3");
+
+ xc_vector_destroy(&vector);
+
+ return 0;
+}
+/* }}} */