在不使用 malloc() 的情况下分配 struct dirent [英] Allocating a struct dirent without malloc()
问题描述
我需要使用 readdir_r()
在多线程程序中读取目录的内容.由于struct dirent
的大小取决于文件系统,man readdir_r
推荐
I need to use readdir_r()
to read the contents of a directory in a multithreaded program. Since the size of struct dirent
is filesystem dependent, man readdir_r
recommends
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;
找到所需的分配大小.分配它
to find the size of the allocation needed. To allocate it
entryp = malloc(len);
被调用,最后readdir_r()
是这样使用的:
is called, and finally readdir_r()
uses it like this:
struct dirent *returned;
readdir_r(DIR*, entryp, &returned);
但是,我想避免调用 malloc()
(或任何其他手动内存管理函数).
However, I'd like to avoid calling malloc()
(or any other manual memory management function).
我想到的一种方法是
_Alignas(struct dirent) char direntbuf[len];
struct dirent *entryp = (struct dirent*) direntbuf;
这应该给出正确对齐的分配,但它违反了严格的别名.但是,缓冲区永远不会通过 char*
访问,因此最有可能的问题,即编译器通过不同类型对缓冲区的访问重新排序,不会发生.
This should give a correctly aligned allocation, but it violates strict aliasing. However, the buffer is never accessed via a char*
so the most likely problem, the compiler reordering accesses to the buffer via different types, cannot occur.
另一种方法是通过 alloca()
,它返回一个 void*
,避免严格的别名问题.然而,alloca()
似乎并不能像 malloc()
和朋友们那样保证对齐.要始终获得对齐的缓冲区,例如
Another way could be by alloca()
, which returns a void*
, avoiding strict aliasing problems. However, alloca()
does not seem to guarantee alignment the way malloc()
and friends do. To always get an aligned buffer, something like
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[]
更明确.
would be needed. In particular, the cast to char *
is needed to perform arithmetic on a pointer, and the cast to uintptr_t
is needed to do the binary &
. This doesn't look more well-defined than allocating a char[]
.
在分配struct dirent
时有没有办法避免手动内存管理?
Is there a way to avoid manual memory management when allocating a struct dirent
?
推荐答案
如何定义这个:
#include <stddef.h> /* For offsetof */
#include <dirent.h>
union U
{
struct dirent de;
char c[offsetof(struct dirent, d_name) + NAME_MAX + 1]; /* NAME_MAX is POSIX. */
};
这篇关于在不使用 malloc() 的情况下分配 struct dirent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!