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
}