Changeset 1551 in svn for trunk/util/xc_vector.h


Ignore:
Timestamp:
2014-11-08T07:38:45Z (5 years ago)
Author:
Xuefer
Message:

merge stack/vector to 1 impl, avoid possible memory leak using malloc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/util/xc_vector.h

    r1044 r1551  
    66#endif /* _MSC_VER > 1000 */
    77
     8#include <string.h>
     9#include <stdlib.h>
     10#include <assert.h>
     11
    812typedef struct {
    9     zend_uint size;
    10     zend_uint cnt;
     13    size_t size;
    1114    void *data;
     15
     16    size_t capacity;
     17    size_t data_size;
     18    int persistent;
    1219} xc_vector_t;
    1320
    14 #define xc_vector_init(type, vector) do { \
    15     (vector)->cnt = 0;     \
    16     (vector)->size = 0;    \
     21#define xc_vector_initializer(type, persistent_) { \
     22    0, \
     23    NULL, \
     24\
     25    0, \
     26    sizeof(type), \
     27    persistent_, \
     28}
     29
     30#define xc_vector_init(type, vector, persistent_) do { \
     31    (vector)->size = 0; \
    1732    (vector)->data = NULL; \
     33\
     34    (vector)->capacity = 0; \
     35    (vector)->data_size = sizeof(type); \
     36    (vector)->persistent = persistent_; \
    1837} while (0)
    1938
    20 #define xc_vector_add(type, vector, value) do { \
    21     if ((vector)->cnt == (vector)->size) { \
    22         if ((vector)->size) { \
    23             (vector)->size <<= 1; \
    24             (vector)->data = erealloc((vector)->data, sizeof(type) * (vector)->size); \
    25         } \
    26         else { \
    27             (vector)->size = 8; \
    28             (vector)->data = emalloc(sizeof(type) * (vector)->size); \
    29         } \
    30     } \
    31     ((type *) (vector)->data)[(vector)->cnt++] = value; \
     39static inline void xc_vector_destroy_impl(xc_vector_t *vector TSRMLS_DC)
     40{
     41    if (vector->data) {
     42        pefree(vector->data, vector->persistent);
     43    }
     44    vector->capacity = 0;
     45    vector->size = 0;
     46}
     47
     48#define xc_vector_destroy(vector) xc_vector_destroy_impl(vector TSRMLS_CC)
     49
     50#define xc_vector_size(vector) ((vector)->size)
     51#define xc_vector_element_ptr_(vector, index) ( \
     52    (void *) ( \
     53        ((char *) (vector)->data) + (index) * (vector)->data_size \
     54    ) \
     55)
     56
     57static inline xc_vector_t *xc_vector_check_type_(xc_vector_t *vector, size_t data_size)
     58{
     59    assert(vector->data_size = data_size);
     60    return vector;
     61}
     62
     63#define xc_vector_data(type, vector) ((type *) xc_vector_check_type_(vector, sizeof(type))->data)
     64
     65static inline void xc_vector_check_reserve_(xc_vector_t *vector TSRMLS_DC)
     66{
     67    if (vector->size == vector->capacity) {
     68        if (vector->capacity) {
     69            vector->capacity <<= 1;
     70            vector->data = perealloc(vector->data, vector->data_size * vector->capacity, vector->persistent);
     71        }
     72        else {
     73            vector->capacity = 8;
     74            vector->data = pemalloc(vector->data_size * vector->capacity, vector->persistent);
     75        }
     76    }
     77}
     78
     79#define xc_vector_push_back(vector, value_ptr) do { \
     80    xc_vector_check_reserve_(vector TSRMLS_CC); \
     81    memcpy(xc_vector_element_ptr_(vector, (vector)->size++), value_ptr, (vector)->data_size); \
    3282} while (0)
    3383
     
    3585{
    3686    void *data = vector->data;
     87
    3788    vector->data = NULL;
     89    vector->capacity = 0;
    3890    vector->size = 0;
    39     vector->cnt = 0;
    4091    return data;
    4192}
    4293
    43 #define xc_vector_detach(type, vector) ((type *) xc_vector_detach_impl(vector))
     94#define xc_vector_detach(type, vector) ((type *) xc_vector_detach_impl(xc_vector_check_type_(vector, sizeof(type))))
    4495
    45 static inline void xc_vector_free_impl(xc_vector_t *vector TSRMLS_DC)
     96static inline xc_vector_t *xc_vector_pop_back_check_(xc_vector_t *vector, size_t data_size)
    4697{
    47     if (vector->data) {
    48         efree(vector->data);
    49     }
    50     vector->size = 0;
    51     vector->cnt = 0;
     98    assert(vector);
     99    assert(vector->data_size == data_size);
     100    assert(vector->capacity > 0);
     101    return vector;
    52102}
    53103
    54 #define xc_vector_free(type, vector) xc_vector_free_impl(vector TSRMLS_CC)
     104#define xc_vector_pop_back(type, vector) xc_vector_data(type, \
     105    xc_vector_pop_back_check_(vector, sizeof(type)) \
     106)[--(vector)->size]
     107
     108static inline void xc_vector_reverse(xc_vector_t *vector)
     109{
     110    char *left, *right;
     111    void *tmp;
     112
     113    assert(vector);
     114    tmp = alloca(vector->data_size);
     115    for (left = vector->data, right = xc_vector_element_ptr_(vector, vector->size - 1); left < right; left += vector->data_size, right -= vector->data_size) {
     116        memcpy(tmp, left, vector->data_size);
     117        memcpy(left, right, vector->data_size);
     118        memcpy(right, tmp, vector->data_size);
     119    }
     120}
    55121
    56122#endif /* XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B */
Note: See TracChangeset for help on using the changeset viewer.