Проблема с использованием std :: copy - PullRequest
7 голосов
/ 24 февраля 2010

При использовании функции копирования std я получаю предупреждение.

У меня есть массив byte, который я объявляю.

byte *tstArray = new byte[length];

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

У меня есть серия операторов if, которые я использую для анализа исходного ввода, и на основе некоторой строки я выбираю, какой байтовый массив использовать, и при этом копирую результаты в исходный tstArray.

Например:

if(substr1 == "15")
{
   std::cout<<"Using byte array rated 15"<<std::endl;
   std::copy(ratedArray15,ratedArray15+length,tstArray);
} 

Предупреждение, которое я получаю, предупреждение C4996: 'std :: copy': вызов функции с параметрами это может быть небезопасно - этот вызов полагается на вызывающего абонента, чтобы проверить, что переданный значения верны.

Возможное решение состоит в том, чтобы отключить это предупреждение, используя -D_SCL_SECURE_NO_WARNINGS, я думаю. Ну, это то, что я исследую.

Но я не уверен, означает ли это, что мой код действительно небезопасен, и мне действительно нужно было провести некоторую проверку?

Ответы [ 4 ]

9 голосов
/ 24 февраля 2010

C4996 означает, что вы используете функцию, помеченную как __declspec(deprecated). Вероятно, использование D_SCL_SECURE_NO_WARNINGS просто #ifdef исключит устаревание. Вы можете прочитать файл заголовка, чтобы знать наверняка.

Но вопрос в том, почему это устарело? Похоже, что MSDN ничего не говорит об этом на странице std :: copy (), но, возможно, я смотрю не на ту страницу. Как правило, это было сделано для всех «небезопасных функций манипуляции со строками» во время мощной защиты XPSP2. Поскольку вы не передаете длину целевого буфера в std :: copy, если вы попытаетесь записать в него слишком много данных, он с радостью запишет за конец буфера.

Чтобы сообщить, небезопасно ли ваше использование, нам потребуется пересмотреть весь ваш код. Обычно существует более безопасная версия, которую они рекомендуют, когда они отказываются от функции таким способом. Вы можете просто скопировать строки другим способом. Эта статья кажется углубленной. Похоже, они подразумевают, что вы должны использовать std :: checked_array_iterator вместо обычного OutputIterator.

Что-то вроде:

stdext::checked_array_iterator<char *> chkd_test_array(tstArray, length);
std::copy(ratedArray15, ratedArray15+length, chkd_test_array);

(Если я правильно понял ваш код.)

4 голосов
/ 24 февраля 2010

По сути, это предупреждение говорит вам о том, что вы должны быть абсолютно уверены, что tstArray указывает на массив, достаточно большой для хранения элементов "length", поскольку std::copy не проверяет это.

1 голос
/ 24 февраля 2010

Что ж, я предполагаю, что односторонний отказ Microsoft от stdlib также включает передачу char* в std::copy. (На самом деле они перепутались с целым рядом функций.)

Я полагаю, что некоторые его части имеют некоторые достоинства (fopen() касается глобального ERRNO, поэтому он не ориентирован на многопоточность), но другие решения не кажутся очень рациональными. (Я бы сказал, что они взяли слишком большую полосу в целом. Должны быть уровни, такие как non-threadsafe, non-checkable и т. Д.)

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

0 голосов
/ 24 февраля 2010

По крайней мере, кажется, что VC ++ 2010 RC не генерирует это предупреждение на уровне предупреждений по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...