Ale*_*ets 8 c struct memory-management alloca
我认为隐藏结构定义会使代码更安全,因为您在编译器的帮助下强制执行,不能直接访问结构的任何成员.缺点是用户无法在堆栈上声明结构类型的变量,因为结构的大小未知,有时需要避免使用malloc().这可以(部分成功)解决,alloca(3)所有主要的libc实现都存在,尽管此函数不符合POSIX.鉴于这种优点和缺点,这样的设计一般可以认为好吗?
在lib.h:
struct foo;
extern size_t foo_size;
int foo_get_bar (struct foo *);
Run Code Online (Sandbox Code Playgroud)
在lib.c:
struct foo {
int bar;
};
size_t foo_size = sizeof foo;
int foo_get_bar (struct foo *foo)
{
return foo->bar;
}
Run Code Online (Sandbox Code Playgroud)
在example.c:
#include "lib.h"
int bar(void) {
struct foo *foo = alloca (foo_size);
foo_init (foo);
return foo_get_bar (foo);
}
Run Code Online (Sandbox Code Playgroud)
UPD:更新了问题,明确指出使用的思想alloca()是能够在堆栈上声明结构但隐藏其定义.
是的,隐藏数据是一个很好的做法。
\n作为该模式的替代方案alloca(foo_size);,可以声明一个对齐的字符数组并执行指针转换。不过,指针转换并不完全可移植。如果大小是由变量而不是编译时常量定义的,则字符数组需要是 VLA:
extern size_t size;\n\nstruct sfoo;\n\n#include <stddef.h>\n\nint main(void) {\n unsigned char _Alignas (max_align_t) cptr[size];\n // or unsigned char _Alignas (_Complex long double) cptr[size]; // some widest type\n struct sfoo *sfooptr = (struct sfoo *) cptr;\n ...\nRun Code Online (Sandbox Code Playgroud)\n如果 VLA 不需要或不可用,请将大小声明为常量 ( #define foo_N 100),保证其大小至少满足需要。