【问题标题】:How do I avoid using a constant for filename size?如何避免使用常量作为文件名大小?
【发布时间】:2019-10-05 16:39:33
【问题描述】:

似乎标准编程实践和 POSIX 标准相互矛盾。我正在使用一个程序,我注意到我看到了很多类似的东西:

char buf[NAME_MAX + 1]

而且我还看到很多操作系统没有定义 NAME_MAX 并说它们在技术上不必根据 POSIX 来定义,因为您应该使用 pathconf 来获取它配置的值在运行时而不是将其硬编码为常量。

问题是编译器不允许我以这种方式对数组使用 pathconf。即使我尝试将 pathconf 的结果存储在一个 const int 中,它仍然会抛出一个合适的结果并说它必须是一个常量。所以看起来为了实际使用pathconf,我必须避免在这里使用一个字符数组作为缓冲区,因为这显然不够好。所以我陷入了困境,因为 C++ 标准似乎不允许我做 POSIX 说我必须做的事情,即在运行时而不是编译时确定文件名的字符缓冲区的大小.

我能找到的唯一信息表明我需要用向量替换数组,但不清楚我会怎么做。当我使用一个简单的程序进行测试时,我可以让它工作:

std::vector<char> buf((pathconf("/", _PC_NAME_MAX) + 1));

然后我可以通过调用buf.size() 或其他方式来计算大小。但我不确定这是否是正确的方法。有没有人有任何尝试让程序停止取决于系统头文件中定义的 NAME_MAXMAXNAMLEN 等常量并让实现在运行时使用 pathconf 的经验?

【问题讨论】:

  • std::string 很有用。
  • 我不熟悉 POSIX 或 pathconf,但一般来说,如果我无法在编译时确定我需要的内存量,我会使用动态内存分配(例如 malloc 或 new)来分配我的 char 数组的内存。这样,您不必指定常量。

标签: c++ arrays vector posix


【解决方案1】:

半途而废的措施确实会导致某种冲突。

const usigned NAME_MAX = /* get the value at runtime */;
char buf[NAME_MAX + 1];

第二行声明了一个 C 风格的数组(大概),用于保存一个 C 风格的字符串。在 C 中,这很好。在 C++ 中,存在一个问题,因为 NAME_MAX 的值在编译时是未知的。这就是为什么我称其为中途衡量标准——混合了 C 风格的代码和 C++ 编译。 (一些编译器会在 C++ 中允许这样做。显然你的不允许。)

C++ 方法将使用 C++ 风格的字符串,如:

std::string buf;

就是这样。无需指定大小,因为将根据需要分配内存,前提是您避免使用 C 样式接口。在合理的情况下使用流式传输 (&gt;&gt;)。如果缓冲区被用户或文件输入填充,这应该是你所需要的。


如果您需要使用 C 风格的字符串(也许这个缓冲区正在由为 C 编写的系统调用填充?),有几个选项可以分配所需的空间。最简单的可能是向量,就像你想的那样。

std::vector<char> buf{NAME_MAX + 1};
system_call(buf.data()); // Send a char* to the system call.

或者,您可以使用 C++ 样式的字符串,这样可以更方便地操作数据。

std::string buf{NAME_MAX + 1, '\0'};
system_call(buf.data()); // Send a char* to the system call.

还有一个智能指针选项,但vector 方法可能更适合为 C 样式数组编写的现有代码。

【讨论】:

    猜你喜欢
    • 2018-04-06
    • 2022-07-22
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 2015-09-05
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多