Такая проверка не защитит вас.
Многие C API имеют своего рода контракт с программистами, использующими его, что они будут подчиняться соглашениям, указанным API, без какого-либо строгого механическое обеспечение выполнения этого контракта. Например, строковые API на основе C в основном утверждают, что строки всегда заканчиваются нулем, и что правильное использование любого строкового API на основе C предполагает и зависит от строки, заканчивающейся нулем.
Когда этот контракт действует, обычно считается безопасным для выполнения таких проверок, потому что лицо, передающее вам строку, должно гарантировать этот контракт, обычно добавляя строку или структуру данных с помощью дополнительное нулевое значение специально и явно для выполнения этого контракта, например:
char string[13] = "Hello World!"; //string[12] contains the value 0
/*...*/
char const* str = string;
do {
char curr = *str++;
if(curr == 0)
break;
/*...*/
} while(true);
В большинстве строковых API на основе C этот код считается "безопасным" в контексте указанного c этого контракт гарантирован.
Но это зависит от поведения программиста, и это не может быть гарантировано. Программисту не понадобится много времени, чтобы плохо себя вести со своим кодом и что-то вроде этого:
char string[12] = "Hello World";
string[11] = '!';
немедленно сломает строку l oop, которую я только что показал. Вот почему программисты на C ++ считают (справедливо, на мой взгляд), что такого рода проверки небезопасны: они просто не могут быть гарантированно правильными, если вы не доверяете своим пользователям (программистам) соблюдать ваши правила.
Вот почему мы предпочитаю API, которые не могут неожиданно сломаться, как это.
std::string string = "Hello World!";
for(char curr : string) { //for-each loop, intrinsically safe unless the iterators are improperly implemented
/*Do whatever with curr*/
}
Итак, вернемся к исходному вопросу: безопасный способ решить эту проблему - использовать объекты, специально предназначенные для нашей безопасности. Используйте std::array<T, N>
вместо T arr[N]
, что позволит использовать циклы for-each. Если вам нужно использовать итерации на основе индекса, предпочтите at(index)
вместо [index]
в любой ситуации, когда производительность не на высоте. Это методы, которые сделают ваш код безопасным, вместо того, чтобы просто полагать, что ваши данные правильно настроены.