Strcpy s c что это

от admin

Name already in use

cpp-docs / docs / c-runtime-library / reference / strcpy-s-wcscpy-s-mbscpy-s.md

  • Go to file T
  • Go to line L
  • Copy path
  • Copy permalink
  • Open with Desktop
  • View raw
  • Copy raw contents Copy raw contents

Copy raw contents

Copy raw contents

strcpy_s , wcscpy_s , _mbscpy_s , _mbscpy_s_l

Copies a string. These versions of strcpy , wcscpy , _mbscpy have security enhancements, as described in Security features in the CRT.

[!IMPORTANT] _mbscpy_s and _mbscpy_s_l cannot be used in applications that execute in the Windows Runtime. For more information, see CRT functions not supported in Universal Windows Platform apps.

dest
Location of the destination string buffer.

dest_size
Size of the destination string buffer in char units for narrow and multi-byte functions, and wchar_t units for wide functions. This value must be greater than zero and not greater than RSIZE_MAX . Ensure that this size accounts for the terminating NULL following the string.

src
Null-terminated source string buffer.

locale
Locale to use.

Zero if successful; otherwise, an error.

dest dest_size src Return value Contents of dest
NULL any any EINVAL not modified
any any NULL EINVAL dest[0] set to 0
any 0, or too small any ERANGE dest[0] set to 0

The strcpy_s function copies the contents in the address of src , including the terminating null character, to the location that’s specified by dest . The destination string must be large enough to hold the source string and its terminating null character. The behavior of strcpy_s is undefined if the source and destination strings overlap.

wcscpy_s is the wide-character version of strcpy_s , and _mbscpy_s is the multibyte-character version. The arguments of wcscpy_s are wide-character strings. The arguments of _mbscpy_s and _mbscpy_s_l are multibyte-character strings. These functions behave identically otherwise. _mbscpy_s_l is identical to _mbscpy_s except that it uses the locale parameter passed in instead of the current locale. For more information, see locale .

If dest or src is a null pointer, or if the destination string size dest_size is too small, the invalid parameter handler is invoked, as described in Parameter validation. If execution is allowed to continue, these functions return EINVAL and set errno to EINVAL when dest or src is a null pointer, and they return ERANGE and set errno to ERANGE when the destination string is too small.

Upon successful execution, the destination string is always null-terminated.

In C++, use of these functions is simplified by template overloads that can infer buffer length automatically, so that you don’t have to specify a size argument. And, they can automatically replace older, less-secure functions with newer, more secure counterparts. For more information, see Secure template overloads.

The debug library versions of these functions first fill the buffer with 0xFE. To disable this behavior, use _CrtSetDebugFillThreshold .

By default, this function’s global state is scoped to the application. To change this behavior, see Global state in the CRT.

Generic-text routine mappings

TCHAR.H routine _UNICODE and _MBCS not defined _MBCS defined _UNICODE defined
_tcscpy_s strcpy_s _mbscpy_s wcscpy_s
Routine Required header
strcpy_s <string.h>
wcscpy_s <string.h> or <wchar.h>
_mbscpy_s <mbstring.h>

These functions are Microsoft-specific. For more compatibility information, see Compatibility.

Unlike production quality code, this sample calls the secure string functions without checking for errors:

When you’re building C++ code, the template versions may be easier to use.

How does strcpy_s work?

As we all know, strcpy_s is a safety version of strcpy.

But I wonder how it works .

let’s see some examples.

strpy_s’s declaration:
errno_t strcpy_s(_CHAR *_DEST, size_t _SIZE, const _CHAR *_SRC)

It will return an assertion.
I think I can understand this, use _SIZE to make sure we can’t copy more characters than _SIZE

But.. I can’t understand this:

we can still get a assertion, how did that happened?

Debug Assertion Failed
expression : (L»Buffer is too small «&&0)

will strcpy_s checks the size of dest inside its body?? and if it’s true , how? how to check a pointer like _DEST?

4 Answers 4

This is actually how to get the size of a stack array at run time without decaying it to a pointer:

You send it as a template reference, and the template mechanism deduces the size. So, you can do something like

So my guess is that this is how the «safe» MS strcpy_s is checking the sizes. Otherwise, if you pass just a pointer, there is NO STANDARD-COMPLIANT way of getting the size.

In DEBUG mode, MicroSoft APIs fill the buffer with 0xfd, so they can check for an overflow.

This function doesn’t truncate the copied string, but raises an exception!

It’s always a pain to specify the size of the dest buffer (use _countof rather than sizeof), mostly when you use a pointer!

I have more problems with those «_s» APIs than with the standards ones!!

MSDN Says «The strcpy_s function copies the contents in the address of strSource, including the terminating null character, to the location that’s specified by strDestination. The destination string must be large enough to hold the source string and its terminating null character. The behavior of strcpy_s is undefined if the source and destination strings overlap.»

Santosh Dhanawade's user avatar

dest cannot hold more than 5 chars, that’s why you get the error. It is not because of _SIZE . If dest was char* then you need to make sure you allocate enough memory for it, you won’t get any compile error. But in your program dest has a fixed size, and strcpy_s , unlike strcpy , checks the size of the destination buffer (if it can, and in this case it can as its size is defined at compile time). Read this

Basically strcpy_s is the «safe» version of strcpy , it doesn’t allow you to overflow. From the standard: C (2011) and ISO/IEC WDTR 24731 — strcpy_s : a variant of strcpy that checks the destination buffer size before copying. Internally, probably strcpy_s asserts sizeof(dest)<SIZE .

Русские Блоги

Использование и меры предосторожности функций strcpy () и strcpy_s () в C ++

При написании программы на C ++ вы неизбежно столкнетесь с функцией strcpy () и ее безопасной версией strcpy_s (). Фактически, причина, по которой вводится версия функции _s, заключается в том, чтобы сделать программирование более безопасным, но для обеспечения безопасности оно также будет Проще сделать наш код "ошибочным". Итак, вот краткое введение в использование и меры предосторожности функций strcpy () и strcpy_s ().

Прежде всего, мы знаем, что как исходная функция strcpy (), так и функция безопасной версии strcpy_s () существуют в заголовочном файле <cstring>, поэтому программа должна начинаться со следующего оператора:

Во-вторых, исходная функция strcpy () является членом, который существует в стандартном пространстве имен std, поэтому для использования функции strcpy () необходимо добавить следующий оператор:

Или каждый раз, когда вы используете функцию strcpy (), ставьте перед ней префикс пространства имен:

Тем не менее, для самых последних редакторов, которые часто используют функцию strcpy (), вы все равно получите сообщение об ошибке, например, в следующем простом примере:

Обычно с синтаксисом проблем нет, но при запуске Visual Studio 2017 сообщит об ошибке, как показано ниже:

Смысл очень прост, просто чтобы сказать вам, что функция strcpy () небезопасна, вы должны вместо этого использовать функцию strcpy_s (). Во-первых, независимо от того, что происходит после перехода на функцию strcpy_s (), теоретически приведенный выше код синтаксически Это логически правильно, так как вы можете избежать того, что редактор заставит вас использовать безопасную версию?

На самом деле, есть много решений, просто чтобы избежать кода ошибки 4996 на картинке выше, вы можете Используйте функцию избирательного предупреждения редактора Добавьте следующее предложение перед оператором включения:

Но это решение иногда не решает проблему. Например, я пробовал VS2017, и он не работал, тогда мы просто Отключить функцию предупреждения Хорошо, способ сделать это — добавить предложение перед #include <stdio.h> следующим образом:

В VS2017 это предложение должно быть добавлено в заголовочный файл "stdafx.h".

После добавления запустите ту же программу еще раз, и она может работать нормально, результаты отображения показаны на следующем рисунке:

Затем решается проблема неиспользования защищенной версии, а затем объясняется случай использования защищенной версии.

Если мы решим доверять редактору, то мы изменим функцию strcpy () на функцию strcpy_s (). После изменения мы сначала столкнемся со следующей ошибкой:

Это потому, что когда мы использовали функцию strcpy () раньше, мы знали, что эта функция является членом стандартного пространства имен std, и Безопасная версия strcpy_s не является членом пространства имен Таким образом, "std ::" должен быть удален, после удаления запустить снова, и он будет работать нормально.

Но иногда при удалении «std ::» редактор все равно получит сообщение об ошибке: 1. Нет экземпляра перегруженной функции "strcpy_s", которая соответствует списку параметров, 2. "strcpy_s": функция не принимает 2 параметра.

Как показано ниже:

Это связано с тем, что существует две версии функции strcpy_s () с двумя и тремя параметрами, если можно гарантировать размер буфера.
с тремя параметрами:
errno_t strcpy_s(
char *strDestination,
size_t numberOfElements,
const char *strSource
);
с двумя параметрами:
errno_t strcpy_s(
char (&strDestination)[size],
const char *strSource
); // C++ only

Таким образом, Если мы используем new для выделения пространства хранения, упомянутая выше проблема не может гарантировать размер буфера. 。

Посмотрите на следующий код:

В синтаксисе нет ничего плохого, но поскольку пространство для хранения str временно выделено с помощью new, размер буфера не может быть гарантирован. Щелкните по запуску, и появятся две вышеуказанные ошибки.

Решение этой ситуации на самом деле очень простое, то есть версия, которая не соответствует 2 параметрам: Версия с 3 параметрами Chant. Между двумя строками добавьте параметр для определения длины.

Итак, полный код выглядит следующим образом:

Здесь используется версия функции strcpy_s () с 2 параметрами и 3 параметрами.

Когда позже используется трехпараметрическая версия, общий подход Установить длину для копирования длина строки +1 Поскольку strlen () возвращает длину строки, но не содержит нулевых символов в конце строки, она равна +1.

Код выше работает так, как показано на следующем рисунке:

Выше приведено основное использование и меры предосторожности для функций strcpy () и strcpy_s (), я надеюсь помочь всем

man pages section 3: Basic Library Functions

These functions copy data from one string (array of characters) to another. Depending on the function, strings may be either terminated by a null character or consist of a length of n bytes. All character counts are measured in individual bytes, even if a string with multibyte characters is used, which may result in copying only part of a multibyte character if the full character does not fit within the byte count specified. They do not check for null pointers, and programs may crash if passing null or otherwise invalid pointers to these functions, or specifying sizes larger than the memory allocation in use for the string. Use of adi(7) may help in detecting buffer overflows or invalid pointer usage in code.

The strcat(), stpcpy(), and strcpy() functions do not check for overflow of the array. Use of one of the bounds-checking variants is recommended instead of those functions.

strcat(), strncat(), strlcat()

The strcat() function appends a copy of string s2, including the terminating null character, to the end of string s1. The strncat() function appends at most n bytes. Each returns a pointer to the null-terminated result. The initial character of s2 is written over the null character at the end of s1. If copying takes place between objects that overlap, the behavior of strcat(), strncat(), and strlcat() is undefined.

The strlcat() function appends at most (dstsizestrlen(dst)-1) characters of src to dst (dstsize being the size of the string buffer dst). If the string pointed to by dst contains a null-terminated string that fits into dstsize bytes when strlcat() is called, the string pointed to by dst will be a null-terminated string that fits in dstsize bytes (including the terminating null character) when it completes, and the initial character of src will override the null character at the end of dst. If the string pointed to by dst is longer than dstsize bytes when strlcat() is called, the string pointed to by dst will not be changed. The function returns min< dstsize , strlen( dst )> + strlen( src ). Insufficient space can be checked for as follows:

strcpy(), stpcpy(), strncpy(), stpncpy(), strlcpy()

The strcpy() and stpcpy() functions copy string s2 to s1, including the terminating null character, stopping after the null character has been copied. The strcpy() function returns s1. The stpcpy() function returns a pointer to the terminating null character copied into the s1 array.

The strncpy() and stpncpy() functions copy not more than n bytes (bytes that follow a null byte are not copied) from the array pointed to by s2 to the array pointed to by s1. If the array pointed to by s2 is a string that is shorter than n bytes, null bytes are appended to the copy in the array pointed to by s1, until n bytes in all are written. If the array pointed to by s2 is a string that is n bytes or longer, the resulting s1 will not be null terminated. The strncpy() function returns s1. If s1 contains null bytes, stpncpy() returns a pointer to the first such null byte. Otherwise, it returns &s1[n].

The strlcpy() function copies at most dstsize−1 characters (dstsize being the size of the string buffer dst) from src to dst, truncating src if necessary. The result is always null-terminated. The function returns strlen(src). Insufficient space can be checked for as follows:

If copying takes place between objects that overlap, the behavior of these functions is undefined.

C11 Bounds Checking Interfaces

The strcpy_s(), strncpy_s(), strcat_s(), strncat_s(), and strlen_s() functions are part of the C11 bounds checking interfaces specified in the C11 standard, Annex K. Each of these functions provides similar functionality to their respective non-bounds checking counterpart functions, but with additional safety checks in the form of explicit runtime constraints as defined in the C11 standard. See runtime_constraint_handler(3C) and INCITS/ISO/IEC 9899:2011.

If no runtime constraint violation is detected, the strcpy_s(), strncpy_s(), strcat_s() and strncat_s() functions return zero. If a runtime constraint violation is detected and the handler returns, they return a non-zero value.

Errors

The C11 bounds checking interface functions will fail if:

Null pointer is passed or source and destination overlap

A size argument is not a valid value

Destination array is too small

The other functions described in this page do not check if a null pointer is passed, and programs passing null pointers to them may crash.

Usage

Usage of the strlcat() and strlcpy() functions is recommended over the other variants to avoid buffer overflows and make code easier to review and maintain.

It is not possible to limit the strcat() and strcpy() functions to a maximum buffer size. Although one can calculate the amount of space needed before calling strcat or strcpy, the use of these functions will always force reviewers to follow the logic, and hinder automated scanning of source code for vulnerabilities.

strncpy() is not guaranteed to null-terminate the destination buffer. This fact, together with the side effect that it will add null bytes if there is space left make it a useful function for updating fixed-length structures that reside on disk, for example, wtmpx(5).

strncat() is hard to use safely as it requires the remaining size of the destination buffer to be calculated by the caller.

Читать:
Как скролить в майнкрафт

Похожие статьи