如何使用visual c++中的strncpy_s函数

How to use the strncpy_s function from visual c++?

本文关键字:函数 strncpy 中的 何使用 visual c++      更新时间:2023-10-16

我正在C++中学习一些新东西,我试图从Visual C++中测试这个strncpy_s函数。然而,当程序崩溃时,我遇到了一些问题,我不知道发生了什么,但我确信这是一个非常愚蠢的问题。源代码是这样的:

#include "stdafx.h"
#include <iostream>
#include <cstdio>
#include <cstring>
int main()
{
    char *p;
    p=(char *)malloc(sizeof(char)*strlen("Hello!n"));
    strncpy_s(p,strlen("Hello!n"),"Hello!n",strlen("Hello!n"));
    std::cout << p;
    std::cout << strlen("Hello!n") << std::endl;
    return 0;
}

正如我所说,我不使用std::string,因为我想尝试这个新函数并了解它是如何工作的。

我收回了我的评论,我更仔细地阅读了文档。您的代码正在传递无效的参数,并且正在调用无效的参数处理程序。也许这就是正在发生的事情。即:

p=(char *)malloc(sizeof(char)*strlen("Hello!n"));

这一行为7个字符分配了空间,这是字符串的长度,但没有足够的空间容纳null终止符。(这通常是一个错误)

strncpy_s的文档中写道:这些函数试图将strSource的前D个字符复制到strDest,其中D是strSource的计数和长度中的较小值如果这些D字符适合strDest(其大小为numberOfElements)中的,并且仍为null终止符留有空间则复制这些字符并附加一个终止null否则,strDest[0]设置为null字符,并调用无效参数处理程序,如参数验证中所述。

您是否可能看到"无效参数处理程序"?

终止字符('')还需要1个字符,因此需要用strlen("Hello!n") + 1替换strlen("Hello!n")。您可以将此长度存储在某个变量中,而不是再次调用strlen。此外,由于您使用C++,您可以使用new / delete而不是malloc / free:

int len = strlen("Hello!n") + 1;
char *p;
p = new char[len];
strncpy_s(p, len, "Hello!n", len);
std::cout << p << len << std::endl;
delete[] p;

"安全增强"字符串函数本质上是为在遇到问题时崩溃而设计的。

来自微软关于strncpy_s():的文档

这些函数试图将strSource的前D个字符复制到strDest,其中D是计数和strSource长度中的较小值。如果这些D字符适合strDest(其大小给定为numberOfElements),并且仍然为null终止符留出空间,然后复制这些字符,并附加终止null;否则,strDest[0]被设置为null字符和无效字符参数处理程序被调用,如参数验证中所述。

上述段落有一个例外。如果计数是_TRUNCATE,则在仍然为总是附加的终止null留有空间。

参数验证的描述是:

当发现无效参数时,C运行时的行为是调用当前分配的无效参数处理程序。默认值无效参数调用Watson崩溃报告,导致应用程序崩溃,并询问用户是否要加载崩溃转储到Microsoft进行分析。在调试模式下,一个无效参数也会导致断言失败。

此行为可以通过使用函数来更改_set_invalid_parameter_handler将无效参数处理程序设置为您自己的函数。。。

您的示例程序提供的缓冲区太小了一个char(没有空终止符的空间)。

因此,除非您特别更改strxxxx_s函数在遇到错误时应该执行的操作,否则您的程序将在设计时崩溃。这个想法是,崩溃比可能打开安全漏洞的漏洞要好。

strlen(s)只会告诉您不带NUL终止符的字符串的长度。要分配用于复制字符串的空间,通常使用strlen(s)+1为NUL终止符添加空间。

您需要分配strlen("Hello!\n")+1(用于null终止符)。sizeof(char)是完全没有意义的,因为在所有平台上sizeof(char)都保证为1。

如果使用C++,为什么要使用malloc或char*?

std::string p = "Hello!n";
std::cout << p;
std::cout << p.length();

std::string* p = new std::string("Hello!n");
std::cout << p;
std::cout << p->length();

但要回答您最初的问题,您可能需要使用strlen(p) + 1

如果您需要字符串中的char*,则可以使用p.c_str()