Aracılığıyla paylaş


Checked Iterators

İşaretli yineleyiciler, kapsayıcınızın sınırlarının geçersiz kılınmamasını sağlar. Denetlenen yineleyiciler hem sürüm derlemeleri hem de hata ayıklama derlemeleri için geçerlidir. Hata ayıklama modunda derleme yaparken hata ayıklama yineleyicilerini kullanma hakkında daha fazla bilgi için bkz . Hata Ayıklama Yineleyici desteği.

Remarks

denetlenen yineleyiciler tarafından oluşturulan uyarıları devre dışı bırakma hakkında bilgi için bkz _SCL_SECURE_NO_WARNINGS. .

denetlenen _ITERATOR_DEBUG_LEVEL yineleyiciler özelliğini etkinleştirmek veya devre dışı bırakmak için önişlemci makrosunu kullanabilirsiniz. 1 veya 2 olarak tanımlanırsa _ITERATOR_DEBUG_LEVEL , yineleyicilerin güvenli olmayan kullanımı çalışma zamanı hatasına neden olur ve program sonlandırılır. 0 olarak tanımlanmışsa, işaretli yineleyiciler devre dışı bırakılır. Varsayılan olarak, için değeri _ITERATOR_DEBUG_LEVEL yayın derlemeleri için 0 ve hata ayıklama derlemeleri için 2'dir.

Important

Daha eski belgeler ve kaynak kodu makroya _SECURE_SCL başvurabilir. öğesini denetlemek _SECURE_SCLiçin kullanın_ITERATOR_DEBUG_LEVEL. Daha fazla bilgi için bkz. _ITERATOR_DEBUG_LEVEL.

1 veya 2 olarak tanımlandığında _ITERATOR_DEBUG_LEVEL , bu yineleyici denetimleri gerçekleştirilir:

  • Tüm standart yineleyiciler (örneğin, vector::iterator) denetlendi.

  • Çıkış yineleyicisi denetlenmiş bir yineleyiciyse, denetim davranışı alma gibi std::copy standart kitaplık işlevlerine çağrır.

  • Çıkış yineleyicisi işaretsiz bir yineleyiciyse, standart kitaplık işlevlerine yapılan çağrılar derleyici uyarılarına neden olur.

  • Aşağıdaki işlevler, kapsayıcı sınırlarının dışında bir erişim varsa bir çalışma zamanı hatası oluşturur:

0 olarak tanımlandığında _ITERATOR_DEBUG_LEVEL :

  • Tüm standart yineleyicilerin işareti kaldırılır. Yineleyiciler kapsayıcı sınırlarının ötesine geçebilir ve bu da tanımsız davranışa yol açar.

  • Çıkış yineleyicisi denetlenmiş bir yineleyiciyse, denetim davranışı alma gibi std::copy standart kitaplık işlevlerine çağrır.

  • Çıkış yineleyicisi işaretsiz bir yineleyiciyse, standart kitaplık işlevlerine yapılan çağrılar işaretsiz davranış alır.

denetlenen yineleyici, kapsayıcının sınırlarını aşmaya çalışırsanız çağıran invalid_parameter_handler bir yineleyiciye başvurur. hakkında invalid_parameter_handlerdaha fazla bilgi için bkz . Parametre Doğrulama.

Denetlenen yineleyicileri destekleyen yineleyici bağdaştırıcıları Sınıf ve unchecked_array_iterator Sınıf'tırchecked_array_iterator.

Examples

1 veya 2 olarak ayarla seçeneğini kullanarak _ITERATOR_DEBUG_LEVEL derleme yaptığınızda, belirli sınıfların dizin işlecini kullanarak kapsayıcı sınırlarının dışındaki bir öğeye erişmeye çalıştığınızda bir çalışma zamanı hatası oluşur.

// checked_iterators_1.cpp
// cl.exe /Zi /MDd /EHsc /W4

#define _ITERATOR_DEBUG_LEVEL 1

#include <vector>
#include <iostream>

using namespace std;

int main()
{
    vector<int> v;
    v.push_back(67);

    int i = v[0];
    cout << i << endl;

    i = v[1]; //triggers invalid parameter handler
}

Bu program "67" yazdırır ve ardından hata hakkında ek bilgiler içeren bir onay hatası iletişim kutusu açar.

Benzer şekilde, 1 veya 2 olarak ayarla seçeneğini kullanarak _ITERATOR_DEBUG_LEVEL derleme yaptığınızda, kapsayıcı boş olduğunda kapsayıcı sınıflarını kullanarak front veya back kullanarak bir öğeye erişmeye çalıştığınızda bir çalışma zamanı hatası oluşur.

// checked_iterators_2.cpp
// cl.exe /Zi /MDd /EHsc /W4
#define _ITERATOR_DEBUG_LEVEL 1

#include <vector>
#include <iostream>

using namespace std;

int main()
{
    vector<int> v;

    int& i = v.front(); // triggers invalid parameter handler
}

Bu program, hata hakkında ek bilgiler içeren bir onay hatası iletişim kutusu açar.

Aşağıdaki kod, her biriyle ilgili yorumlar içeren çeşitli yineleyici kullanım örneği senaryolarını gösterir. Varsayılan olarak, _ITERATOR_DEBUG_LEVEL Hata ayıklama derlemelerinde 2 ve Perakende derlemelerinde 0 olarak ayarlanır.

// checked_iterators_3.cpp
// cl.exe /MTd /EHsc /W4

#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <numeric>
#include <string>
#include <vector>

using namespace std;

template <typename C>
void print(const string& s, const C& c)
{
    cout << s;

    for (const auto& e : c)
    {
        cout << e << " ";
    }

    cout << endl;
}

int main()
{
    vector<int> v(16);
    iota(v.begin(), v.end(), 0);
    print("v: ", v);

    // OK: vector::iterator is checked in debug mode
    // (i.e. an overrun causes a debug assertion)
    vector<int> v2(16);
    transform(v.begin(), v.end(), v2.begin(), [](int n) { return n * 2; });
    print("v2: ", v2);

    // OK: back_insert_iterator is marked as checked in debug mode
    // (i.e. an overrun is impossible)
    vector<int> v3;
    transform(v.begin(), v.end(), back_inserter(v3), [](int n) { return n * 3; });
    print("v3: ", v3);

    // OK: array::iterator is checked in debug mode
    // (i.e. an overrun causes a debug assertion)
    array<int, 16> a4;
    transform(v.begin(), v.end(), a4.begin(), [](int n) { return n * 4; });
    print("a4: ", a4);

    // OK: Raw arrays are checked in debug mode
    // (an overrun causes a debug assertion)
    // NOTE: This applies only when raw arrays are given to C++ Standard Library algorithms!
    int a5[16];
    transform(v.begin(), v.end(), a5, [](int n) { return n * 5; });
    print("a5: ", a5);

    // WARNING C4996: Pointers cannot be checked in debug mode
    // (an overrun causes undefined behavior)
    int a6[16];
    int * p6 = a6;
    transform(v.begin(), v.end(), p6, [](int n) { return n * 6; });
    print("a6: ", a6);

    // OK: stdext::checked_array_iterator is checked in debug mode
    // (an overrun causes a debug assertion)
    int a7[16];
    int * p7 = a7;
    transform(v.begin(), v.end(), stdext::make_checked_array_iterator(p7, 16), [](int n) { return n * 7; });
    print("a7: ", a7);

    // WARNING SILENCED: stdext::unchecked_array_iterator is marked as checked in debug mode
    // (it performs no checking, so an overrun causes undefined behavior)
    int a8[16];
    int * p8 = a8;
    transform(v.begin(), v.end(), stdext::make_unchecked_array_iterator(p8), [](int n) { return n * 8; });
    print("a8: ", a8);
}

Derleyiciyi kullanarak cl.exe /EHsc /W4 /MTd checked_iterators_3.cpp bu kodu derlediğinizde bir uyarı yayar, ancak hatasız bir yürütülebilir dosyaya derlenir:

algorithm(1026) : warning C4996: 'std::_Transform1': Function call with parameters
that may be unsafe - this call relies on the caller to check that the passed values
are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation
on how to use Visual C++ 'Checked Iterators'

Komut satırında çalıştırıldığında yürütülebilir dosya şu çıkışı oluşturur:

v: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
v2: 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30
v3: 0 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45
a4: 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60
a5: 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75
a6: 0 6 12 18 24 30 36 42 48 54 60 66 72 78 84 90
a7: 0 7 14 21 28 35 42 49 56 63 70 77 84 91 98 105
a8: 0 8 16 24 32 40 48 56 64 72 80 88 96 104 112 120

See also

C++ Standart Kitaplığına Genel Bakış
Hata Ayıklama Yineleyici Desteği