在不使用 malloc() 的情况下分配 struct dirent [英] Allocating a struct dirent without malloc()

查看:57
本文介绍了在不使用 malloc() 的情况下分配 struct dirent的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆