1

可能重复:
如何找到 sizeof(指向数组的指针)

在第一次调用 strcpy_s 时,编译器可以推断出数组长度,但在第二次调用中,必须传入数组长度。

TCHAR szTemp[512];
::strcpy_s(szTemp, "a long text message");

TCHAR* pszTemp = new TCHAR[512];
::strcpy_s(pszTemp, 512, "a long text message");
delete []pszTemp;

编译器如何做到这一点?这是微软唯一的扩展吗?另外,我如何声明我的方法以利用参数推导?

4

5 回答 5

6

在第一次使用时strcpy_s,数组中元素的数量szTemp是类型的一部分szTemp(因为它是一个“512的数组TCHAR”),所以编译器知道它并可以完成声明的模板strcpy_s

在第二种用法中strcpy_s, ,pszTemp是一个指针(它是一个“指向 ” 的指针TCHAR),而不是一个数组,指向的元素数量不是类型的一部分。通常,编译器无法知道指针指向的位置有多少元素。(在这种情况下,编译器可能会推导出它,因为前面的代码显示了它,但这增加了编译器和通常被认为不值得实现的语言的复杂性。)

要自己执行此操作,请按照声明的方式声明模板strcpy_s

template <size_t size> errno_t strcpy_s(
    char (&strDestination)[size],
    const char *strSource 
); 

这声明了一个基于 parameter的模板,该模板用于一个函数,其第一个参数的类型为“引用元素size数组”。当编译器看到第一个参数是 char 的 512 个元素的数组的使用时,它能够将此参数与模板中的参数相匹配,并推断为 512。sizecharstrcpy_ssize

在其他地方,您将拥有模板的定义(不仅仅是声明)。size该定义可以在其代码中使用模板参数。当编译器看到 的使用时strcpy_s,它将以size512 的特化实例化模板定义。

这仅适用于 C++,不适用于 C,因为 C 没有模板。

于 2012-12-12T19:51:25.403 回答
2

根据docsstrcpy_s作为具体函数存在,但也作为模板函数为已知大小的szTemp数组(例如您提供的数组)重载。在这种情况下,数组的大小是函数定义的模板参数。

strcpy_s它本身是 Microsoft 独有的函数,因此模板版本并不比接受指针的版本更特定于 Microsoft。

于 2012-12-12T19:48:14.350 回答
1

在第一种情况下,使用模板函数(doc),所以没有魔法:

template <size_t size>
errno_t strcpy_s(
   char (&strDestination)[size],
   const char *strSource 
); // C++ only
于 2012-12-12T19:50:38.750 回答
1

它可以推断 szTemp 的数组长度,因为它被声明为数组。对于 pszTemp,它被声明为一个指针,没有办法推断它的长度。

据说有一些第三方 strcpy_s 实现,但主要是微软的事情——这是他们努力加强安全漏洞的一部分。

于 2012-12-12T19:50:55.427 回答
1

第一种是使用模板,例如:

template <size_t N>
strcpy_s(char (&dest)[N], char const *source) { 
    // ...
}

在模板内部,N是传递的数组的大小。

在第二种情况下,pszTemp是指针而不是数组,因此它与模板参数(需要实际数组)不匹配,因此您需要显式传递目标大小。

于 2012-12-12T19:49:33.213 回答