errno_t _dupenv_s(
char **buffer,
size_t *sizeInBytes,
const char *varname
);
我有几个问题:
**
)的指针而不是指针(*
)?sizeInBytes
是必要的,strlen(buffer)
答案 0 :(得分:4)
在msvc下以_s
为后缀的任何函数都是一个安全函数,这意味着它不会对传递的数据的完整性做出任何假设。由于这个原因,字符串的长度是必需的,因为你不能假设它的空终止或终止(你可能只想要一半的字符串,但那是副作用)。
安全功能全部返回错误代码,以便可以检查它们而不会出现错误,因此需要通过指针发送任何返回。并将其视为strdup
&的非安全版本dupenv
返回char*
,得到双重间接,以便指向您传递的变量的指针获取已分配缓冲区的地址。
答案 1 :(得分:0)
不,它要求字符指针的地址。该方法将分配必要的空间来保存变量的值并设置指向它的指针的值,否则为NULL。请参阅页面下方的示例代码:
http://msdn.microsoft.com/en-us/library/ms175774(v=VS.80).aspx
答案 2 :(得分:0)
在此上下文中,类型char**
是指向char
数组的指针。 (它也可以指向指向单个char
的指针,但这不是它与_dupenv_s()
一起使用的方式。)
_dupenv_s()
函数通过要求操作系统保留一些足以容纳它的内存块来分配char
数组。操作系统保留一块内存,并为_dupenv_s()
函数提供此新分配的char
数组的地址。 _dupenv_s()
函数将此数组的地址存储到char*
变量中,因为它是指向char
s数组的指针。
现在,函数必须将此char*
值传递给调用者,以便调用代码可以使用它。返回值已用于返回错误代码,因此无法使用。但是,让我们说调用者有一个char*
变量准备好接收分配缓冲区的地址。
如果_dupenv_s()
函数知道调用者的char*
变量所在的位置,则该函数可以继续并使用正确的值填充调用者的char*
变量。为此,调用者需要传递调用者的char*
变量的地址。也就是说,您需要将指针传递给指向chars
数组的指针。这意味着必须通过char**
。
请注意,这也是sizeInBytes
为size_t*
的原因。调用者有一个变量size_t
,调用者可以将变量的地址作为size_t*
传递给函数,这样函数就可以用正确的值填充变量。
虽然strlen(buffer) == sizeInBytes
可能属实,但strlen()
函数通过计算字符数来确定字符串的长度,直到它看到空终止符。 strlen()
完成所需的时间量与字符数成线性关系,即它不是常数。为什么不跳过要求调用者这样做并直接提供大小的麻烦?
如果指针仍然让您感到困惑(并且有时令人困惑),this Stack Overflow answer可能会有所帮助。