【问题标题】:how can I replace strcpy with strcpy_s?如何用 strcpy_s 替换 strcpy?
【发布时间】:2019-06-01 02:36:37
【问题描述】:

运行代码后,出现以下错误。如何用 strcpy_s 替换 strcpy?谢谢你的帮助。而且当我尝试直接用 strcpy_s 替换 strcpy 时,它说命名空间“std”没有成员“strcpy_s”。

严重性代码描述项目文件行抑制状态 错误 C4996 'strcpy':此函数或变量可能不安全。考虑改用 strcpy_s。要禁用弃用,请使用 _CRT_SECURE_NO_WARNINGS。详细信息请参见在线帮助。 Nuitrack_project e:\nuitracksdk\nuitrack\include\nuitrack\types\issue.h 71

严重性代码描述项目文件行抑制状态 错误 C4996 'strcpy':此函数或变量可能不安全。考虑改用 strcpy_s。要禁用弃用,请使用 _CRT_SECURE_NO_WARNINGS。详细信息请参见在线帮助。 Nuitrack_project e:\nuitracksdk\nuitrack\include\nuitrack\types\issue.h 81

#ifndef NUITRACK_ISSUE_H_
#define NUITRACK_ISSUE_H_

#include <memory>
#include <string>
#include<cstring>

namespace tdv
{
namespace nuitrack
{
/**
 * @ingroup CommonElements_group
 * @brief Describes an issue identifier.
 */
enum IssueId
{
    NONE_ISSUE = 0,
    FRAME_BORDER_ISSUE = 1,
    OCCLUSION_ISSUE = 2,
    SENSOR_ISSUE = 3
};

/**
 * @ingroup CommonElements_group
 * @brief Stores general information about a issue.
 * 
 * Parent class of all issue classes.
 */
class Issue
{
public:
     /**
     * @brief Smart pointer to access the Issue instance.
     */
    typedef std::shared_ptr<Issue> Ptr;

    /**
     * @brief Returns the issue type as a string.
     */
    static std::string getType()
    {
        static std::string _type = "Issue";
        return _type;
    }

    /**
     * @brief Returns the issue name.
     */
    virtual std::string getName() const
    {
            return std::string(_name);
    }

    /**
     * @brief Returns the issue identifier.
     */
    IssueId getId()
    {
        return _id;
    }

    /**
     * @brief Constructs a default issue.
     */
    Issue() :
        _id(NONE_ISSUE)
   {
        std::string name = "Issue";
        _name = new char[name.length() + 1];
        std::strcpy(_name, name.c_str());
    }

    /**
     * @brief Constructs an issue object from its identifier and name.
     */
    Issue(IssueId id, const std::string &name) :
        _id(id)
    {
        _name = new char[name.length() + 1];
        std::strcpy(_name, name.c_str());
    }

    virtual ~Issue()
    {
        deleteString();
    }

    /**
     * Release the memory occupied by the string representation of the name.
     */
    void deleteString()
    {
        if(_name)
        {
            delete[] _name;
            _name = NULL;
        }
    }

    /**
     * @brief Copy constructor.
     */
    Issue(const Issue& issue)
    {
        copyIssue(issue);
    }

    /**
     * @brief Overloaded copy assignment operator.
     */
    void operator=(const Issue& issue)
    {
        copyIssue(issue);
    }

protected:
    /** @warning For internal use only. */
    IssueId _id;
    /** @warning For internal use only. */
    char* _name;

private:
    void copyIssue(const Issue& issue)
    {
        _id = issue._id;

        uint32_t nameSize = 0;
        while(issue._name[nameSize] != '\0')
            nameSize++;

        _name = new char[nameSize + 1];
        for(uint32_t i = 0; i <= nameSize; i++)
            _name[i] = issue._name[i];
    }
};

} /* namespace nuitrack */
} /* namespace tdv */

#endif /* NUITRACK_ISSUE_H_ */

【问题讨论】:

  • 你为什么混合使用std::string和原始指针?
  • 鉴于您知道目的地的大小足够大,我并没有真正看到strcpy_s 的优势,只是它让您有更多犯错的机会。
  • 除此之外,strcpy_s 只是 C 库的一部分,而不是 C++ 版本,因此您不能使用 std:: 命名空间前缀。
  • 最好只是禁用这些警告,strcpy_s 不会增加任何真正的安全性,甚至可能会增加错误的范围

标签: c++


【解决方案1】:

strcpy_s(“s”代表“安全”)允许您指定目标缓冲区的大小。 std::strcpy 不这样做,因此如果您的源代码太长,则允许您写入超过目标缓冲区的末尾,从而产生不良影响。

在上述第一种情况下,试试这个:

_name = new char[name.length() + 1];
strcpy_s(_name, name.length() + 1, name.c_str());

简单地用 strcpy_s 替换 strcpy 不起作用,原因有两个: 1) strcpy_s 接受另一个参数(目标缓冲区的长度) 2) strcpy_s 不是 std 的一部分,即 std 命名空间不包含 strcpy_s 的声明

所以尝试添加额外的参数,并将“std:strcpy”替换为“strcpy_s”

如果您使用 Visual Stdio 之类的 IDE,您通常可以右键单击“strcpy_s”之类的术语,从出现的上下文菜单中选择“转到声明”之类的内容,然后快速获取有关该术语的一些信息.

  • 鲍勃

注意:如果您不熟悉编译和构建 C/C++ 程序的机制,也许有必要解释一下错误消息。该消息告诉您,如果您想使用传统的“不安全”c 调用,例如 strcpy,您可以通过将 _CRT_SECURE_NO_WARNINGS 添加到构建系统的预处理器定义中来实现。这可以是包含相关标头之前的#define,也可以是 IDE 中某处的条目。如果您输入该定义,您的编译器将允许您毫无怨言地使用 std::strcpy。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-01
    • 2021-06-23
    • 2017-11-29
    • 2015-11-15
    • 2013-11-27
    • 2020-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多