С++ 'strcpy' дает предупреждение (C4996)

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

что это значит?

'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.

Ответы

Ответ 1

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

Ответ 2

В то время как strcpy является общей строковой функцией, у нее есть история, которая является источником многих ошибок и явлений безопасности в программном обеспечении (из-за простоты переполнения буфера).

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

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

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

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

Ответ 3

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

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

Ответ 4

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

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

  • если вы не уверены - сделайте то, что говорит VС++, и используйте "безопасные" функции. Они вызовут обработчик ошибок, который завершит вашу программу, если что-то пойдет не так.
  • Если вы знаете, что делаете, вы знаете, что никакого переполнения никогда не произойдет, и все краевые случаи обрабатываются вашим кодом - определите _CRT_SECURE_NO_WARNINGS до включения заголовков CRT, и это заставит предупреждение уйти.

Ответ 5

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

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

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

Ответ 6

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

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

Ответ 7

#pragma warning(disable: 4996)

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

Ответ 8

Если вы посмотрели на плюсы и минусы использования метода пуриста С++, а не на беспокойство, потому что вы знаете, что ваши строки будут завершены нулем, тогда вы также можете отключить предупреждение в 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 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

Ответ 9

использовать Защищенные перегрузки шаблонов или определить функции обертки работа для динамически распределенных буферов, поэтому эта попытка бесполезна.
Либо измените источник, чтобы использовать безопасную замену, либо просто проигнорируйте его.

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

игнорировать метод 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)