stclib / STC

A modern, user friendly, generic, type-safe and fast C99 container library: String, Vector, Sorted and Unordered Map and Set, Deque, Forward List, Smart Pointers, Bitset and Random numbers.
MIT License
1.34k stars 73 forks source link

Trying to use vector with custom memory allocator #70

Closed leonsal closed 1 year ago

leonsal commented 1 year ago

Hi,

I am trying to use a vector with a custom memory allocator and I followed the example Per container-instance customization. I am probably doing something wrong because the compiler complains (see below). Is there something missing in the allocator definition ? Regards.

Errors from: clang -I stc/include -fsanitize=address,leak main.c my_alloc.c -o vec

stc/include/stc/cvec.h:311:36: error: too many arguments provided to function-like macro invocation
        _cx_value* d = (_cx_value*)i_realloc(self->data, cap*c_sizeof(i_key));
                                   ^
stc/include/stc/priv/template.h:51:21: note: expanded from macro 'i_realloc'
  #define i_realloc c_JOIN(i_allocator, _realloc)
                    ^
stc/include/stc/ccommon.h:50:22: note: expanded from macro 'c_JOIN'
#define c_JOIN(a, b) c_JOIN0(a, b)
                     ^
stc/include/stc/ccommon.h:49:23: note: expanded from macro 'c_JOIN0'
#define c_JOIN0(a, b) a ## b
                      ^
<scratch space>:32:1: note: expanded from here
alloc_realloc
^
./my_alloc.h:12:53: note: expanded from macro 'alloc_realloc'
#define alloc_realloc(p, sz)    my_realloc(c_extend(self)->ctx, p, sz)
                                                    ^
stc/include/stc/extend.h:59:9: note: macro 'c_extend' defined here
#define c_extend() c_container_of(self, _cx_MEMB(_ext), get)
        ^
In file included from main.c:13:
In file included from ./my_alloc.h:18:
In file included from stc/include/stc/extend.h:66:
stc/include/stc/cvec.h:311:36: error: use of undeclared identifier 'c_extend'
        _cx_value* d = (_cx_value*)i_realloc(self->data, cap*c_sizeof(i_key)

my_alloc.c

#include <stdlib.h>
#include <stdio.h>

void* my_malloc(void* ctx, size_t sz) {
    printf("my_malloc(%p, %lu)\n", ctx, sz);
    return malloc(sz);
}

void* my_calloc(void* ctx, size_t n, size_t sz) {
    printf("my_calloc(%p, %lu, %lu)\n", ctx, n, sz);
    return calloc(n, sz);
}

void* my_realloc(void* ctx, void* p, size_t sz) {
    printf("my_realloc(%p, %p, %lu)\n", ctx, p, sz);
    return realloc(p, sz);
}

void my_free(void* ctx, void* p) {
    printf("my_free(%p, %p)\n", ctx, p);
    free(p);
}

my_alloc.h

#ifndef MY_ALLOC_H
#define MY_ALLOC_H
#include <stdlib.h>

void* my_malloc(void* ctx, size_t sz);
void* my_calloc(void* ctx, size_t n, size_t sz);
void* my_realloc(void* ctx, void* p, size_t sz);
void  my_free(void* ctx, void* p);

#define alloc_malloc(sz)        my_alloc(c_extend(self)->ctx, sz)
#define alloc_calloc(n, sz)     my_calloc(c_extend(self)->ctx, n, sz)
#define alloc_realloc(p, sz)    my_realloc(c_extend(self)->ctx, p, sz)
#define alloc_free(p)           my_free(c_extend(self)->ctx, p)

#define i_allocator     alloc
#define i_no_clone
#define i_extend        void* ctx;
#include "stc/extend.h"

#endif

main.c

#include <stdlib.h>
#include <stdint.h>

// Vector using standard allocator
#define i_type vi32
#define i_key  int32_t
#include "stc/cvec.h"

// Vector using "my allocator"
#define i_type vu32
#define i_base cvec
#define i_key  uint32_t
#include "my_alloc.h"

int main(int argc, char* argv[]) {

    vi32 v1;
    vi32_push(&v1, 1);
    vi32_drop(&v1);

    vu32_ext v2 = {.ctx = NULL};
    vu32_push(&v2.get, 1);
    vu32_drop(&v2.get);
    return 0;
}
tylov commented 1 year ago

Hi. Yes there is a bug in the docs, will fix it (point 1.).

  1. c_extend() does not take any arguments (self is used internally).
  2. You forgot to init v1 to {0};
  3. STC uses purely signed integers for sizes and indices, i.e. also for the allocator functions - consider to change from size_t to intptr_t (or ptrdiff_t if you prefer) to avoid warning with -Wconversion, and cast to size_t in the calls to std alloc functions.

Otherwise, this works as expected.