Hata: stack-use-after-scope
Adres Temizleme Hatası: Kapsam dışı yığın belleği kullanımı
Bir değişkenin kullanım ömrünün sözcük temelli kapsamının dışında bir yığın adresinin kullanılması C veya C++'da birçok şekilde gerçekleşebilir.
Örnek 1 - basit iç içe yerel
// example1.cpp
// stack-use-after-scope error
int *gp;
bool b = true;
int main() {
if (b) {
int x[5];
gp = x+1;
}
return *gp; // Boom!
}
Bu örneği derlemek ve test etmek için visual studio 2019 sürüm 16.9 veya sonraki bir geliştirici komut isteminde şu komutları çalıştırın:
cl example1.cpp /fsanitize=address /Zi
devenv /debugexe example1.exe
Sonuç hatası - basit iç içe yerel
Örnek 2 - lambda yakalama
// example2.cpp
// stack-use-after-scope error
#include <functional>
int main() {
std::function<int()> f;
{
int x = 0;
f = [&x]() {
return x; // Boom!
};
}
return f(); // Boom!
}
Bu örneği derlemek ve test etmek için visual studio 2019 sürüm 16.9 veya sonraki bir geliştirici komut isteminde şu komutları çalıştırın:
cl example2.cpp /fsanitize=address /Zi
devenv /debugexe example2.exe
Sonuç hatası - lambda yakalama
Örnek 3 - yerel ayarlarla yıkıcı sıralaması
// example3.cpp
// stack-use-after-scope error
#include <stdio.h>
struct IntHolder {
explicit IntHolder(int* val = 0) : val_(val) { }
~IntHolder() {
printf("Value: %d\n", *val_); // Bom!
}
void set(int* val) { val_ = val; }
int* get() { return val_; }
int* val_;
};
int main(int argc, char* argv[]) {
// It's incorrect to use "x" inside the IntHolder destructor,
// because the lifetime of "x" ends earlier. Per the C++ standard,
// local lifetimes end in reverse order of declaration.
IntHolder holder;
int x = argc;
holder.set(&x);
return 0;
}
Bu örneği derlemek ve test etmek için visual studio 2019 sürüm 16.9 veya sonraki bir geliştirici komut isteminde şu komutları çalıştırın:
cl example3.cpp /fsanitize=address /Zi /O1
devenv /debugexe example3.exe
Sonuçta oluşan hata - yıkıcı sıralama
Örnek 4 - geçiciler
// example4.cpp
// stack-use-after-scope error
#include <iostream>
struct A {
A(const int& v) {
p = &v;
}
void print() {
std::cout << *p;
}
const int* p;
};
void explicit_temp() {
A a(5); // the temp for 5 is no longer live;
a.print();
}
void temp_from_conversion() {
double v = 5;
A a(v); // local v is no longer live.
a.print();
}
void main() {
explicit_temp();
temp_from_conversion();
}
Bu örneği derlemek ve test etmek için visual studio 2019 sürüm 16.9 veya sonraki bir geliştirici komut isteminde şu komutları çalıştırın:
cl example4.cpp /EHsc /fsanitize=address /Zi /Od
devenv /debugexe example4.exe
ASAN bir dinamik analiz biçimidir, yani yalnızca gerçekte yürütülen hatalı kodu algılayabilir. İyileştirici, içinde depolanan p
adresten okumak yerine bu durumlarda değerini v
yayabilir. Sonuç olarak, bu örnek bayrağı gerektirir /Od
.
Sonuçta oluşan hata - geçiciler
Ayrıca bkz.
AddressSanitizer'a genel bakış
AddressSanitizer bilinen sorunları
AddressSanitizer derlemesi ve dil başvurusu
AddressSanitizer çalışma zamanı başvurusu
AddressSanitizer gölge baytları
AddressSanitizer bulut veya dağıtılmış test
AddressSanitizer hata ayıklayıcısı tümleştirmesi
AddressSanitizer hata örnekleri