Aracılığıyla paylaş


Hata ayıklama Yineleyici desteği

Visual c++ çalışma zamanı kitaplığı yanlış Yineleyici kullanımı algılar ve onaylama işlemleri ve çalışma zamanında bir iletişim kutusu görüntüler. Yineleyici hata ayıklama desteğini etkinleştirmek için programınızı derlemek için c Çalışma Zamanı Kitaplığı'nın bir hata ayıklama sürümü kullanmanız gerekir. Daha fazla bilgi için bkz. crt kitaplığı özellikleri. Yineleyicilerde kullanma hakkında daha fazla bilgi için bkz: İşaretli Yineleyiciler.

Standart c++ nasıl üye işlevlerini geçersiz hale bir kapsayıcı yineleyiciler neden olabilir açıklar. İki örnek bulunmaktadır:

  • Bir kapsayıcı öğe silme öğesine geçersiz hale gelmesine yineleyiciler neden olur.

  • Boyutunu artırarak bir vektör (itme veya Ekle) içine yineleyiciler neden olan vector geçersiz hale gelmesine.

Örnek

Hata ayıklama modunda aşağıdaki programı derleyin, çalışma zamanında onaylama işlemi sonlandırmak ve.

/* compile with /EHsc /MDd */
#include <vector>
#include <iostream>

int main() {
   std::vector<int> v ;
   
   v.push_back(10);
   v.push_back(15);
   v.push_back(20);
   
   std::vector<int>::iterator i = v.begin();
   ++i;
   
   std::vector<int>::iterator j = v.end();
   --j;
   
   std::cout<<*j<<'\n';
   
   v.insert(i,25); 
   
   std::cout<<*j<<'\n'; // Using an old iterator after an insert
}

Simgesini kullanabilirsiniz _HAS_ITERATOR_DEBUGGING Yineleyici hata ayıklama hata ayıklama yapı özelliği devre dışı bırakmak için. Aşağıdaki programı onaylama değil, ancak yine de tanımsız davranışı tetikler.

Önemli

Use _ITERATOR_DEBUG_LEVEL to control _HAS_ITERATOR_DEBUGGING.Daha fazla bilgi için bkz. _ITERATOR_DEBUG_LEVEL.

// iterator_debugging.cpp
// compile with: /EHsc /MDd
#define _HAS_ITERATOR_DEBUGGING 0
#include <vector>
#include <iostream>

int main() {
   std::vector<int> v ;
   
   v.push_back(10);
   v.push_back(15);
   v.push_back(20);
   
   std::vector<int>::iterator i = v.begin();
   ++i;
   
   std::vector<int>::iterator j = v.end();
   --j;
   
   std::cout<<*j<<'\n';
   
   v.insert(i,25); 
   
   std::cout<<*j<<'\n'; // Using an old iterator after an insert
}
  

Yeniden başlatılmadan önce aşağıda gösterildiği gibi bir yineleyici kullanmaya çalışırsanız bir assert oluşur.

/* compile with /EHsc /MDd */
#include <string>
using namespace std;
int main() {
   string::iterator i1, i2;
   if (i1 == i2)
      ;
}

Aşağıdaki kod örneği için bir onaylama işlemi neden olan iki yineleyiciler için for_each algoritması uyumsuz. Algoritmalar için sağlanan yineleyiciler aynı kapsayıcı başvuruyorsunuz belirlemek için denetleyin.

/* compile with /EHsc /MDd */
#include <algorithm>
#include <vector>
using namespace std;

int main()
{
    vector<int> v1;
    vector<int> v2;

    v1.push_back(10);
    v1.push_back(20);

    v2.push_back(10);
    v2.push_back(20);

    // The next line will assert because v1 and v2 are
    // incompatible.
    for_each(v1.begin(), v2.end(), [] (int& elem) { elem *= 2; } );
}

Bu örnek lambda ifadesi kullanır dikkat edin [] (int& elem) { elem *= 2; } yerine bir functor. Bu seçenek hiçbir boşluğunu assert hatası durumunda olmasına karşın — benzer functor aynı hataya neden olur — lambda olan kompakt işlevi nesne görevleri yerine getirmek için çok kullanışlı bir yol. Lambda ifadeleri hakkında daha fazla bilgi için bkz: Lambda ifadeleri C++.

Hata ayıklama yineleyici de denetimi içinde bildirilen bir yineleyici değişken neden olan bir for yetersiz olması için döngü ne zaman kapsam for döngü kapsamı sona erer.

// debug_iterator.cpp
// compile with: /EHsc /MDd
#include <vector>
#include <iostream>
int main() {
   std::vector<int> v ;
   
   v.push_back(10);
   v.push_back(15);
   v.push_back(20);
   
   for (std::vector<int>::iterator i = v.begin() ; i != v.end(); ++i)
   ;
   --i;   // C2065
}

Hata ayıklama yineleyiciler basit olmayan yıkıcı vardır. Bir yıkıcı çalışmazsa, herhangi bir nedenle erişim ihlalleri ve veri bozulması oluşabilir. Bu örneði ele alalým:

/* compile with: /EHsc /MDd */
#include <vector>
struct base {
   // FIX: uncomment the next line
   // virtual ~base() {}
};

struct derived : base {
   std::vector<int>::iterator m_iter;
   derived( std::vector<int>::iterator iter ) : m_iter( iter ) {}
   ~derived() {}
};

int main() {
   std::vector<int> vect( 10 );
   base * pb = new derived( vect.begin() );
   delete pb;  // doesn't call ~derived()
   // access violation
}

Ayrıca bkz.

Başvuru

Standart C++ Kitaplığı genel bakış