strcpy_s和strcpy()函数的功能几乎是一样的。strcpy函数,就象gets函数一样,它没有方法来保证有效的缓冲区尺寸,所以它只能假定缓冲足够大来容纳要拷贝的字符串。在程序运行时,这将导致不可预料的行为。用strcpy_s就可以避免这些不可预料的行为。

strcpy_s是strcpy的安全版本,它之所以安全,是因为其在拷贝字符串的时候会有越界的检查工作。以下是strcpy_s的实现代码,在tcscpy_s.inl文件可以找到:

/***
*tcscpy_s.inl - general implementation of _tcscpy_s
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* This file contains the general algorithm for strcpy_s and its variants.
*
****/ _FUNC_PROLOGUE
errno_t __cdecl _FUNC_NAME(_CHAR *_DEST, size_t _SIZE, const _CHAR *_SRC)
{
_CHAR *p;
size_t available; /* validation section */
_VALIDATE_STRING(_DEST, _SIZE);
_VALIDATE_POINTER_RESET_STRING(_SRC, _DEST, _SIZE); p = _DEST;
available = _SIZE;
while ((*p++ = *_SRC++) != 0 && --available > 0)
{
} if (available == 0)
{
_RESET_STRING(_DEST, _SIZE);
_RETURN_BUFFER_TOO_SMALL(_DEST, _SIZE);
}
_FILL_STRING(_DEST, _SIZE, _SIZE - available + 1);
_RETURN_NO_ERROR;
}

_VALIDATE_STRING应该是验证字符串的合法性,是否以null结尾。

_VALIDATE_POINTER_RESET_STRING应该是记录字符串的原始信息,以便拷贝失败以后恢复。

当目的地空间不够时,会根据_VALIDATE_POINTER_RESET_STRING记录的信息恢复字符串,并且(在Debug模式下)以弹出对话框的形式报告错误。

_FILL_STRING完成在字符串最后加上null结束符的工作。

正确用法:

int n = 6;
char **argsmy = new char *[n];
int maxlen = 600;
for(int i = 0; i < n; i ++)
{
argsmy[i] = new char [maxlen];// args[i];
}
strcpy_s(argsmy[1],maxlen,"e");
strcpy_s(argsmy[2],maxlen,"Lzma_");
strcat_s(argsmy[2], 600, cTAppEncTop.getBitstreamFile());
strcpy_s(argsmy[3],maxlen,"-BS12");
strcpy_s(argsmy[4],maxlen,"-CN0");
strcpy_s(argsmy[5],maxlen,"-d15");

错误用法:

argsmy[2] = "Lzma_"; strcpy_s(argsmy[2],maxlen,"see");

原因:

argsmy[2] = "Lzma_"; //因为 argsmy[2] 是个指针。他指向一块分配的空间 ,长度 maxlen。

而这样赋值后,指针指向位置变了。而再strcpy_s(argsmy[2],maxlen,"see"); 实际上是将常数变量空间强制赋值。因此出问题。

strcpy_s 用法:

errno_t strcpy_s(
char *strDestination,
size_t numberOfElements,
const char *strSource
); template <size_t size>
errno_t strcpy_s(
char (&strDestination)[size],
const char *strSource
); // C++ only

例子:

// crt_strcpy_s.cpp
// This program uses strcpy_s and strcat_s
// to build a phrase.
// #include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h> int main( void )
{
char string[80];
// using template versions of strcpy_s and strcat_s:
strcpy_s( string, "Hello world from " );
strcat_s( string, "strcpy_s " );
strcat_s( string, "and " );
// of course we can supply the size explicitly if we want to:
strcat_s( string, _countof(string), "strcat_s!" ); printf( "String = %s/n", string );
}

最新文章

  1. TodoMVC中的Backbone+MarionetteJS+RequireJS例子源码分析之三 Views
  2. centos 安装mongodb
  3. web.config 配置
  4. weex环境搭建
  5. html5设计原理(转)
  6. [转]VS2010中如何创建一个WCF
  7. Javascript异步编程方法总结
  8. DTD限制XML文件
  9. cmd 命令设置UTF8
  10. postgresql基本语句
  11. 使用disqus搭建comment时一件非常二的事
  12. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl
  13. Hibernate各保存方法之间的差 (save,persist,update,saveOrUpdte,merge,flush,lock)等一下
  14. Java遍历二叉树深度宽度
  15. Netty 学习 一、初识Netty【原创】
  16. 小程序重新封装打印函数console.log
  17. [MV] - You Give REST a Bad Name
  18. python32模拟鼠标和键盘操作
  19. 【golang-GUI开发】Qt5的安装
  20. Hyper-v带宽限制以及验证工具

热门文章

  1. (七十八)使用第三方框架INTULocationManager实现定位
  2. hashmap简单实例(个人使用经验)
  3. Xcode中Groups和Folder的区别
  4. CSS House
  5. 新手推荐:Hadoop安装教程_单机/伪分布式配置_Hadoop-2.7.1/Ubuntu14.04
  6. Java 8新特性探究(一) JEP126特性lambda表达式和默认方法
  7. Demand Side Platform
  8. numpy教程:矩阵matrix及其运算
  9. Java实现简易的文件的迁移器
  10. 【Qt编程】基于Qt的词典开发系列&lt;六&gt;--界面美化设计