C ++ 'strcpy' выдает предупреждение (C4996) - PullRequest
15 голосов
/ 25 октября 2010

Я получаю это предупреждение, но все функции работают нормально.

что это на самом деле означает?

'strcpy': This function or variable may be unsafe. 
Consider using strcpy_s instead. To disable deprecation, 
use _CRT_SECURE_NO_WARNINGS. See online help for details.

Ответы [ 9 ]

21 голосов
/ 25 октября 2010

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

11 голосов
/ 25 октября 2010

Несмотря на то, что strcpy является обычной строковой функцией, она имеет историю появления множества ошибок и дыр в безопасности программного обеспечения (из-за простоты переполнения буфера).

Microsoft, стремясь содействовать более безопасному кодированию на C и C ++, предоставила набор функций замены для опасных строковых методов. Как правило, у них есть оригинальное имя, добавленное после _s. Следовательно, безопасной версией Microsoft strcpy является strcpy_s, как рекомендуется в предупреждении. Обратите внимание, что это особенность Microsoft, она не вездесущая.

У вас есть несколько вариантов.

  1. DEFINE _CRT_SECURE_NO_WARNINGS, если вы не хотите заботиться об этом, оставляя возможность проблем с безопасностью в вашем программном обеспечении.
  2. Замените ваши строковые функции на безопасные, в результате чего ваше программное обеспечение станет менее переносимым
  3. Оберните функции защищенной строки и везде используйте оболочки, обеспечивая повышенную безопасность на платформах Windows и возвращаясь к традиционным версиям на других платформах. Функции-обёртки могут быть через MACRO или скомпилированные функции.

Обычно я делаю # 3.

10 голосов
/ 25 октября 2010

Поскольку вы программируете на C ++, правильное решение состоит в том, чтобы исключить строки кода в стиле C char* из вашего кода, где это возможно, и заменить их на std::string (или другой подходящий тип строки).

Не не используйте такие функции, как strcpy или strcpy_s или strncpy. Используйте конструктор копирования или оператор присваивания класса string. Или, если вам действительно нужно скопировать буферы, используйте std::copy.

8 голосов
/ 25 октября 2010

Поскольку VC ++ 8 strcpy() и огромный набор других функций считаются небезопасными , поскольку они не имеют проверки границ и могут привести к переполнению буфера при неправильном использовании.

У вас есть два варианта:

  • , если вы не уверены - делайте то, что говорит VC ++, и используйте «безопасные» функции.Они вызовут обработчик ошибок, который прекратит работу вашей программы, если что-то пойдет не так.
  • если вы знаете, что делаете, вы знаете, что переполнения не произойдет, и все крайние случаи обрабатываются вашим кодом - определите_CRT_SECURE_NO_WARNINGS до включения заголовков CRT, и это заставит предупреждение исчезнуть.
4 голосов
/ 25 октября 2010

Существует способ избежать этого предупреждения, по-прежнему использовать strcpy и быть в безопасности:

Вы можете включить безопасные перегрузки шаблона . Они будут (если возможно) определять длину используемых буферов, захватывая их с помощью шаблонных перегрузок. Для меня загадка, почему это не включено по умолчанию в Visual C ++.

4 голосов
/ 25 октября 2010

Это предупреждение в основном сообщает вам, что strcpy устарела, поскольку копирование строки до \0 может легко привести к неприятным проблемам (переполнению буфера). Причина, по которой strcpy все еще существует и работает, заключается в том, что он является частью стандартной библиотеки, но вам действительно следует рассмотреть возможность использования функций str * _s или strn * (которые не зависят исключительно от поиска завершающего \0).

Поскольку переполнения буфера связаны не только с проблемами безопасности, но также и с ошибками, которые относительно сложно отследить и исправить, использование простых функций vanilla str * не только не одобряется, но может привести к тому, что люди будут отклонять ваш код по своей сути. небезопасный.

Подробнее: http://www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html

2 голосов
/ 29 августа 2015
#pragma warning(disable: 4996)

используйте вышеуказанный код в первой строке вашего кода.

1 голос
/ 24 июля 2013

Если вы посмотрели на плюсы и минусы использования пуристической техники C ++, а не на беспокойство, потому что вы «знаете», что ваши строки будут заканчиваться нулем, то вы также можете отключить предупреждение в msvc, такого рода вещи: *

#ifdef _MSC_VER
  // 4231: nonstandard extension used : 'extern' before template explicit instantiation
  // 4250: dominance
  // 4251: member needs to have dll-interface
  // 4275: base needs to have dll-interface
  // 4660: explicitly instantiating a class that's already implicitly instantiated
  // 4661: no suitable definition provided for explicit template instantiation request
  // 4786: identifer was truncated in debug information
  // 4355: 'this' : used in base member initializer list
  // 4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation
#   pragma warning(disable: 4231 4250 4251 4275 4660 4661 4786 4355 4910)
#endif
0 голосов
/ 14 июня 2013

use Secure Template Overloads или определяют функции-оболочки не работают для динамически распределяемых буферов, поэтому эта попытка бесполезна.
Либо измените источник для использования безопасной замены, либо просто проигнорируйтеit.

если коды пишутся самостоятельно, вам лучше изменить такой strcpy на strcpy_s и т. д. Если модули импортированы из надежных источников, вы можете игнорировать предупреждение.

ignoreметод 1: область действия глобуса проекта: добавить _CRT_SECURE_NO_WARNINGS
игнорировать метод 2: игнорировать конкретный модуль: если только один или два из них, вы можете просто запретить предупреждение для этих модулей, если они включены:

#pragma warning(push)
#pragma warning(disable: 4996)
#include <sapi.h>  //legacy module
#include <sphelper.h> //legacy module
#pragma warning(pop)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...