我需要使用readdir_r()
来读取多线程程序中目录的内容。由于struct dirent
的大小依赖于文件系统,man readdir_r
建议在没有malloc的情况下分配struct dirent()
name_max = pathconf(dirpath, _PC_NAME_MAX);
if (name_max == -1) /* Limit not defined, or error */
name_max = 255; /* Take a guess */
len = offsetof(struct dirent, d_name) + name_max + 1;
找到所需要的分配的大小。其分配
entryp = malloc(len);
叫,最后readdir_r()
使用它是这样的:
struct dirent *returned;
readdir_r(DIR*, entryp, &returned);
不过,我想避免调用malloc()
(或任何其他手动内存管理功能)。我想过的
一种方法是
_Alignas(struct dirent) char direntbuf[len];
struct dirent *entryp = (struct dirent*) direntbuf;
这应该给正确对齐的分配,但它违反了严格别名。但是,缓冲区永远不会通过char*
访问,所以最可能的问题是,编译器重新排序通过不同类型访问缓冲区不会发生。
另一种方法可能是alloca()
,它返回void*
,避免严格的别名问题。然而,alloca()
似乎并不能保证malloc()
和朋友的方式一致。总是得到一个对齐的缓冲区,像
void *alloc = alloca(len + _Alignof(struct dirent));
struct dirent *direntbuf = (struct dirent*)((uintptr_t)&((char*)alloc)[_Alignof(struct dirent)]&-_Alignof(struct dirent));
将需要。特别是,需要转换为char *
才能在指针上执行算术运算,并且需要转换为uintptr_t
才能执行二进制&
。这看起来没有比分配char[]
更明确。
在分配struct dirent
时有没有办法避免手动内存管理?
对于<= C99:计算'len'按您的回答,然后定义'字符缓冲区[长度]'。 – alk
@alk:'char buffer [len]'不一定为'struct dirent'正确对齐。另外,根据C. – EOF
,通过类型为“struct dirent”的指针取消引用类型为“char”的对象是未定义的行为。对于char类型数组,您是“*但它违反严格别名*”吗? – alk