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