рдЬреАрд╕реАрд╕реА рдбреЙрдХреНрдпреВрдореЗрдВрдЯреЗрд╢рди рд╕реЗ рдЙрджреНрдзрд░рдг [1]:рдПрдХ рдлрдВрдХреНрд╢рди рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд▓реАрдирдЕрдк рдПрд╕реЗрдЯ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рддрдм рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдПрдХ рд╡реЗрд░рд┐рдПрдмрд▓ рд╕реНрдХреЛрдк рд╕реЗ рдмрд╛рд╣рд░ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗрд╡рд▓ рдСрдЯреЛ рдЪрд░ рдкрд░ рд▓рд╛рдЧреВ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ, рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдпрд╛ рд╕реНрдерд┐рд░ рдЪрд░ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░, рдЪрд░ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддрдХ рд▓реЗрдирд╛ рдЪрд╛рд╣рд┐рдПред рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд░рд┐рдЯрд░реНрди рдорд╛рди, рдпрджрд┐ рдХреЛрдИ рд╣реЛ, рдХреЛ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдпрджрд┐ -fexception рд╡рд┐рдХрд▓реНрдк рд╕рдХреНрд╖рдо рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рд╕реНрдЯреИрдХ рдЕрдирд╡рд╛рдЙрдВрдб рд╣реЛрдиреЗ рдкрд░ рдХреНрд▓реАрдирдЕрдк_рдлрдВрдХреНрд╢рди рдлрд╝рдВрдХреНрд╢рди рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдЕрдкрд╡рд╛рдж рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╕рдлрд╛рдИ рд╡рд┐рд╢реЗрд╖рддрд╛ рдЕрдкрд╡рд╛рдж рдирд╣реАрдВ рдкрдХрдбрд╝рддреА рд╣реИ, рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рдХреНрд░рд┐рдпрд╛ рдХрд░рддреА рд╣реИред рдпрджрд┐ рдХреНрд▓реАрдирдЕрдк_рдлрдВрдХреНрд╢рди рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ, рддреЛ рд╡реНрдпрд╡рд╣рд╛рд░ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИред
рд╕рдлрд╛рдИ рд╡рд┐рд╢реЗрд╖рддрд╛ gcc рдФрд░ clang рд╕рдВрдХрд▓рдХ рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рд╣реИредрдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдХреНрд▓реАрдирдЕрдк рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ рдФрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреА рдЖрдВрддрд░рд┐рдХ рд╕рдВрд░рдЪрдирд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реВрдВрдЧрд╛, рдЬреЛ рдХрд┐ std рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд▓реАрдирдЕрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ :: unique_ptr рдФрд░ std :: share_ptr рдПрдирд╛рд▓реЙрдЧреНрд╕ рд╕реА рдореЗрдВредрдореЗрдореЛрд░реА рдбреАрд▓реЛрдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рд╕рдлрд╛рдИ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:#include<stdlib.h>
#include<stdio.h>
static void free_int(int **ptr)
{
free(*ptr);
printf("cleanup done\n");
}
int main()
{
__attribute__((cleanup(free_int))) int *ptr_one = (int *)malloc(sizeof(int));
return 0;
}
рд╣рдо рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдкреНрд░реЛрдЧреНрд░рд╛рдо "рдХреНрд▓реАрдирдЕрдк рдХрд┐рдпрд╛" рдкреНрд░рд┐рдВрдЯ рдХрд░рддрд╛ рд╣реИред рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЪреАрдпрд░реНрд╕редрд▓реЗрдХрд┐рди рдПрдХ рджреЛрд╖ рддреБрд░рдВрдд рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ: рд╣рдо рдмрд╕ рдирд╣реАрдВ рд▓рд┐рдЦ рд╕рдХрддреЗ__attribute__((cleanup(free_int)))
рдХреНрдпреЛрдВрдХрд┐ рдХреНрд▓реАрдирдЕрдк рд╡рд┐рд╢реЗрд╖рддрд╛ рджреНрд╡рд╛рд░рд╛ рдХрд╣реЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рд╕рдВрдХреЗрддрдХ рдХреЛ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдореБрдХреНрдд рдЪрд░ рдореЗрдВ рд▓реЗ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЖрд╡рдВрдЯрд┐рдд рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддрдХ рд╣реИ, рдЕрд░реНрдерд╛рдд, рд╣рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдбрдмрд▓ рдкреЙрдЗрдВрдЯрд░ рд▓реЗрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдЖрд╡рд░рдг рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:static void free_int(int **ptr)
{
free(*ptr);
...
}
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдХрд┐рд╕реА рднреА рдЪрд░ рдХреЛ рдореБрдХреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдХреНрдпреЛрдВрдХрд┐ рдЙрдиреНрд╣реЗрдВ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:static void _free(void *p) {
free(*(void**) p);
printf("cleanup done\n");
}
рдЕрдм рд╡рд╣ рдХрд┐рд╕реА рднреА рд╕рдВрдХреЗрдд рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд╕рдХрддреА рд╣реИредрдпрд╣рд╛рдБ рдПрдХ рдФрд░ рдЙрдкрдпреЛрдЧреА рдореИрдХреНрд░реЛ рд╣реИ ( рд╕рд┐рд╕реНрдЯрдо рдХреЛрдб рдмреЗрд╕ рд╕реЗ ):#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \
static inline void func##p(type *p) { \
if (*p) \
func(*p); \
} \
struct __useless_struct_to_allow_trailing_semicolon__
рдЬрд┐рд╕реЗ рдмрд╛рдж рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, pclose);
#define _cleanup_pclose_ __attribute__((cleanup(pclosep)))
рд▓реЗрдХрд┐рди рд╡рд╣ рд╕рдм рдирд╣реАрдВ рд╣реИред рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ рдЬреЛ рдЗрд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдиреВрдареЗ_ptr рдФрд░ shared_ptr pluses рдХреЗ рдПрдирд╛рд▓реЙрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ: https://github.com/Snaipe/libcsptrрдЙрдкрдпреЛрдЧ рдХрд╛ рдЙрджрд╛рд╣рд░рдг ([2] рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛):#include <stdio.h>
#include <csptr/smart_ptr.h>
#include <csptr/array.h>
void print_int(void *ptr, void *meta) {
(void) meta;
printf("%d\n", *(int*) ptr);
}
int main(void) {
smart int *ints = unique_ptr(int[5], {5, 4, 3, 2, 1}, print_int);
for (size_t i = 0; i < array_length(ints); ++i) {
ints[i] = i + 1;
}
return 0;
}
рд╕рдм рдХреБрдЫ рдЕрджреНрднреБрдд рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ!рдФрд░ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕ рдЬрд╛рджреВ рдХреЗ рдЕрдВрджрд░ рдХреНрдпрд╛ рд╣реИред рдЖрдЗрдП рдЕрдиреВрдареЗ_ptr рд╕реЗ рд╢реБрд░реБрдЖрдд рдХрд░реЗрдВ (рдФрд░ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рд╕рд╛рдЭрд╛ рдХрд░реЗрдВ):# define shared_ptr(Type, ...) smart_ptr(SHARED, Type, __VA_ARGS__)
# define unique_ptr(Type, ...) smart_ptr(UNIQUE, Type, __VA_ARGS__)
рдЖрдЗрдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдЦрд░рдЧреЛрд╢ рдЫреЗрдж рдХрд┐рддрдирд╛ рдЧрд╣рд░рд╛ рд╣реИ:# define smart_arr(Kind, Type, Length, ...) \
({ \
struct s_tmp { \
CSPTR_SENTINEL_DEC \
__typeof__(__typeof__(Type)[Length]) value; \
f_destructor dtor; \
struct { \
const void *ptr; \
size_t size; \
} meta; \
} args = { \
CSPTR_SENTINEL \
__VA_ARGS__ \
}; \
void *var = smalloc(sizeof (Type), Length, Kind, ARGS_); \
if (var != NULL) \
memcpy(var, &args.value, sizeof (Type)); \
var; \
})
рдЕрдм рддрдХ, рд╕реНрдкрд╖реНрдЯрддрд╛ рдореЗрдВ рд╡реГрджреНрдзрд┐ рдирд╣реАрдВ рд╣реБрдИ рд╣реИ, рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рдЗрд╕ рднрд╛рд╖рд╛ рдХреА рд╕рд░реНрд╡рд╢реНрд░реЗрд╖реНрда рдкрд░рдВрдкрд░рд╛рдУрдВ рдореЗрдВ рдореИрдХреНрд░реЛрдЬрд╝ рдХрд╛ рдПрдХ рдЬрдВрдмрд▓ рд╣реЛред рд▓реЗрдХрд┐рди рд╣рдо рдкреАрдЫреЗ рд╣рдЯрдиреЗ рдХреЗ рдЕрднреНрдпрд╕реНрдд рдирд╣реАрдВ рд╣реИрдВред рдЙрд▓рдЭрди рдХреЛ рд╣рдЯрд╛рдПрдВ:define CSPTR_SENTINEL .sentinel_ = 0,
define CSPTR_SENTINEL_DEC int sentinel_;
...
typedef void (*f_destructor)(void *, void *);
рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХрд░реЗрдВ:# define smart_arr(Kind, Type, Length, ...) \
({ \
struct s_tmp { \
int sentinel_; \
__typeof__(__typeof__(Type)[Length]) value; \
void (*)(void *, void *) dtor; \
struct { \
const void *ptr; \
size_t size; \
} meta; \
} args = { \
.sentinel_ = 0, \
__VA_ARGS__ \
}; \
void *var = smalloc(sizeof (Type), Length, Kind, ARGS_); \
if (var != NULL) \
memcpy(var, &args.value, sizeof (Type)); \
var; \
})
рдФрд░ рд╕рдордЭрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЛ рдХрд┐ рдпрд╣рд╛рдБ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрд░рдЪрдирд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕реЗрдВрдЯрд┐рдирд▓_ рд╡реЗрд░рд┐рдПрдмрд▓, рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рд░рдгреА (рдкреНрд░рдХрд╛рд░) [рд▓рдВрдмрд╛рдИ], рдПрдХ рдбрд┐рд╕реНрдЯреНрд░рдХреНрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░, рдЬреЛ рдореИрдХреНрд░реЛ рддрд░реНрдХреЛрдВ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд (...) рднрд╛рдЧ рдореЗрдВ рдФрд░ рдПрдХ рдореЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдкрд╛рд░рд┐рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХреЛрдВ рд╕реЗ рднреА рднрд░рд╛ рд╣реЛрддрд╛ рд╣реИред рдЖрдЧреЗ рдПрдХ рдХреЙрд▓ рд╣реИsmalloc(sizeof (Type), Length, Kind, ARGS_);
рд╕реНрдорд╛рд▓реЛрдХ рдХреНрдпрд╛ рд╣реИ? рд╣рдореЗрдВ рдХреБрдЫ рдФрд░ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореИрдЬрд┐рдХ рдорд┐рд▓рддреЗ рд╣реИрдВ (рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреБрдЫ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХрд░ рджрд┐рдпрд╛ рд╣реИ):enum pointer_kind {
UNIQUE,
SHARED,
ARRAY = 1 << 8
};
typedef struct {
CSPTR_SENTINEL_DEC
size_t size;
size_t nmemb;
enum pointer_kind kind;
f_destructor dtor;
struct {
const void *data;
size_t size;
} meta;
} s_smalloc_args;
__attribute__ ((malloc)) void *smalloc(s_smalloc_args *args);
# define smalloc(...) \
smalloc(&(s_smalloc_args) { CSPTR_SENTINEL __VA_ARGS__ })
рдЦреИрд░, рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рд╣рдо рд╕реА рдХреЛ рдкреНрдпрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рджрд╕реНрддрд╛рд╡реЗрдЬ рднреА рд╣реИ (рдкрд╡рд┐рддреНрд░ рд▓реЛрдЧ, рдореИрдВ рд╣рд░ рдХрд┐рд╕реА рдХреЛ рдЙрдирд╕реЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд▓реЗрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ): рд╕реНрдореЙрд▓реЛрдХ ()рдлрд╝рдВрдХреНрд╢рди рдПрд▓реЛрдХреЗрдЯрд░ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдореЙрд▓реЛрдХ (3)) рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рд▓реМрдЯрд╛ рд╣реБрдЖ рд╕реВрдЪрдХ "рд╕реНрдорд╛рд░реНрдЯ" рд╕реВрдЪрдХ рд╣реИред <...> рдпрджрд┐ рдЖрдХрд╛рд░ 0 рд╣реИ, рддреЛ NULL рд╡рд╛рдкрд╕ рдЖ рдЧрдпрд╛ рд╣реИред рдпрджрд┐ nmemb 0 рд╣реИ, рддреЛ smalloc рдХрдо рд╕реЗ рдХрдо рд╕рд╛рдЗрдЬ рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рдореЗрдореЛрд░реА рдмреНрд▓реЙрдХ рдореЗрдВ рдПрдХ рд╕реНрдорд╛рд░реНрдЯ рдкреЙрдЗрдВрдЯрд░ рд▓реМрдЯрд╛рдПрдЧрд╛, рдФрд░ рдПрдХ рд╕реНрдорд╛рд░реНрдЯ рд╕реНрдХреЗрд▓рд░ рдкреЙрдЗрдВрдЯрд░, рдпрджрд┐ nmemb 0 рдХреЗ рдмрд░рд╛рдмрд░ рдирд╣реАрдВ рд╣реИ, рддреЛ рдХрдо рд╕реЗ рдХрдо рд╕рд╛рдЗрдЬ рдХреЗ рдореЗрдореЛрд░реА рдмреНрд▓реЙрдХ рдХреЗ рд▓рд┐рдП рдкреЙрдЗрдВрдЯрд░ рдХрдо рд╕реЗ рдХрдо nmemb рд▓реМрдЯрд╛ рд╣реИ, рдФрд░ рдкреЙрдЗрдВрдЯрд░ рдЯрд╛рдЗрдк рдПрд░реЗ рдХрд╛ рд╣реИредрдореВрд▓┬лThe smalloc() function calls an allocator (malloc (3) by default), such that the returned pointer is a smart pointer. <...> If size is 0, then smalloc() returns NULL. If nmemb is 0, then smalloc shall return a smart pointer to a memory block of at least size bytes, and the smart pointer is a scalar. Otherwise, it shall return a memory block to at least size * nmemb bytes, and the smart pointer is an array.┬╗
рдпрд╣рд╛рдБ рд▓рдШреБ рдХрд╛ рд╕реНрд░реЛрдд рд╣реИ:__attribute__ ((malloc)) void *smalloc(s_smalloc_args *args) {
return (args->nmemb == 0 ? smalloc_impl : smalloc_array)(args);
}
рдЖрдЗрдП рдХреЛрдб smalloc_impl рдХреЛ рджреЗрдЦреЗрдВ, рдЕрджрд┐рд╢ рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдЖрд╡рдВрдЯрдиред рд╡реЙрд▓реНрдпреВрдо рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рд╕рд╛рдЭрд╛ рдкреЙрдЗрдВрдЯрд░реНрд╕ рд╕реЗ рдЬреБрдбрд╝реЗ рдХреЛрдб рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдФрд░ рдЗрдирд▓рд╛рдЗрди рдФрд░ рдореИрдХреНрд░реЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди:static void *smalloc_impl(s_smalloc_args *args) {
if (!args->size)
return NULL;
size_t aligned_metasize = align(args->meta.size);
size_t size = align(args->size);
size_t head_size = sizeof (s_meta);
s_meta_shared *ptr = malloc(head_size + size + aligned_metasize + sizeof (size_t));
if (ptr == NULL)
return NULL;
char *shifted = (char *) ptr + head_size;
if (args->meta.size && args->meta.data)
memcpy(shifted, args->meta.data, args->meta.size);
size_t *sz = (size_t *) (shifted + aligned_metasize);
*sz = head_size + aligned_metasize;
*(s_meta*) ptr = (s_meta) {
.kind = args->kind,
.dtor = args->dtor,
.ptr = sz + 1
};
return sz + 1;
}
рдпрд╣рд╛рдВ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдЪрд░ рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХреА рдЧрдИ рд╣реИ, рд╕рд╛рде рд╣реА s_meta рдХрд╛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╣реЗрдбрд░ рдкреНрд▓рд╕ рдЖрдХрд╛рд░ рдХрд╛ рдПрдХ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреНрд╖реЗрддреНрд░ args-> meta.size рд╢рдмреНрдж рдХреЗ рдЖрдХрд╛рд░ рдХреЗ рд╕рд╛рде рдЧрдардмрдВрдзрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╕рд╛рде рд╣реА рдПрдХ рдФрд░ рд╢рдмреНрдж (sizeof (tt))ред рдлрд╝рдВрдХреНрд╢рди рдЪрд░ рдХреЗ рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░ рд▓реМрдЯрд╛рддрд╛ рд╣реИ: ptr + head_size + align_metasize + 1.рдорд╛рди 42 рдХреЗ рд╕рд╛рде рдЖрд░рдВрднреАрдХреГрдд рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдХ рдЪрд░ рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:smart void *ptr = unique_ptr(int, 42);
рдпрд╣рд╛рдБ рд╕реНрдорд╛рд░реНрдЯ рдПрдХ рдореИрдХреНрд░реЛ рд╣реИ:# define smart __attribute__ ((cleanup(sfree_stack)))
рдЬрдм рдкреЙрдЗрдВрдЯрд░ рдЧреБрдВрдЬрд╛рдЗрд╢ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ, sfree_stack рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ:CSPTR_INLINE void sfree_stack(void *ptr) {
union {
void **real_ptr;
void *ptr;
} conv;
conv.ptr = ptr;
sfree(*conv.real_ptr);
*conv.real_ptr = NULL;
}
рдирд┐: рд╢реБрд▓реНрдХ рд╕рдорд╛рд░реЛрд╣ (рд╕рдВрдХреНрд╖рд┐рдкреНрдд):void sfree(void *ptr) {
s_meta *meta = get_meta(ptr);
dealloc_entry(meta, ptr);
}
Dealloc_entry рдлрд╝рдВрдХреНрд╢рди, рдореВрд▓ рд░реВрдк рд╕реЗ, рдПрдХ рдХрд╕реНрдЯрдо рдбрд┐рд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ рдпрджрд┐ рд╣рдордиреЗ рдЗрд╕реЗ рдЕрдиреВрдареЗ_ рддрд░реНрдХ рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕реВрдЪрдХ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИред рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдмрд╕ рдореБрдлреНрдд (рдореЗрдЯрд╛) рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИредрд╕реВрддреНрд░реЛрдВ рдХреА рд╕реВрдЪреА:[1] рдЖрдо рдЪрд░ рдЧреБрдг ред[реи] GCC рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫрд╛ рдФрд░ рдореБрд╣рд╛рд╡рд░реЗрджрд╛рд░ рддрд░реАрдХрд╛ __attribute __ ((рд╕рдлрд╛рдИ)) рдФрд░ рд╕реВрдЪрдХ рдШреЛрд╖рдгрд╛рдПрдБ ред[рей] рдЬреАрд╕реАрд╕реА рдореЗрдВ __cleanup__ рдЪрд░ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред